From: "Daniel P. Berrange" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Gerd Hoffmann <kraxel@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>
Subject: [Qemu-devel] [PATCH v1 RFC 27/34] io: pull Buffer code out of VNC module
Date: Fri, 17 Apr 2015 15:22:30 +0100 [thread overview]
Message-ID: <1429280557-8887-28-git-send-email-berrange@redhat.com> (raw)
In-Reply-To: <1429280557-8887-1-git-send-email-berrange@redhat.com>
The Buffer code in the VNC server is useful for the IO channel
code, so pull it out into a shared module, QIOBuffer.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
include/io/buffer.h | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++
io/Makefile.objs | 1 +
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, 276 insertions(+), 148 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 3bf7656..b415753 100644
--- a/io/Makefile.objs
+++ b/io/Makefile.objs
@@ -1,3 +1,4 @@
+util-obj-y += buffer.o
util-obj-y += task.o
util-obj-y += channel.o
util-obj-y += channel-unix.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 2ddd259..9733dfc 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 c8ee203..333c35e 100644
--- a/ui/vnc-jobs.c
+++ b/ui/vnc-jobs.c
@@ -53,7 +53,7 @@ struct VncJobQueue {
QemuCond cond;
QemuMutex mutex;
QemuThread thread;
- Buffer buffer;
+ QIOBuffer buffer;
bool exit;
QTAILQ_HEAD(, VncJob) jobs;
};
@@ -166,7 +166,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);
@@ -195,7 +195,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)
@@ -272,10 +272,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);
@@ -309,7 +310,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 93a7b35..d3ca97e 100644
--- a/ui/vnc-ws.c
+++ b/ui/vnc-ws.c
@@ -85,8 +85,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) {
@@ -101,7 +101,7 @@ void vncws_handshake_read(void *opaque)
if (handshake_end) {
qemu_set_fd_handler2(vs->csock, NULL, 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");
@@ -117,8 +117,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;
}
@@ -136,7 +136,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,
@@ -152,10 +152,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);
@@ -168,13 +168,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_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
@@ -257,8 +257,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;
@@ -285,12 +285,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)
@@ -344,7 +344,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 9494225..5437102 100644
--- a/ui/vnc-ws.h
+++ b/ui/vnc-ws.h
@@ -79,13 +79,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 f55776e..af1f792 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -651,49 +651,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)
{
@@ -1224,10 +1181,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);
@@ -1257,7 +1214,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]);
@@ -1379,7 +1336,7 @@ static long 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_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
@@ -1495,8 +1452,8 @@ static long vnc_client_read_plain(VncState *vs)
int 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;
@@ -1554,7 +1511,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;
}
@@ -1563,13 +1520,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_handler2(vs->csock, NULL, 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 814d720..f44a949 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -33,6 +33,7 @@
#include "ui/console.h"
#include "audio/audio.h"
#include "qemu/bitmap.h"
+#include "io/buffer.h"
#include <zlib.h>
#include <stdbool.h>
@@ -55,13 +56,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;
@@ -194,15 +188,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];
@@ -213,18 +207,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;
@@ -295,10 +289,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 */
@@ -320,7 +314,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()
@@ -538,14 +532,6 @@ int vnc_client_io_error(VncState *vs, int 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 */
--
2.1.0
next prev parent reply other threads:[~2015-04-17 15:59 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-17 14:22 [Qemu-devel] [PATCH v1 RFC 00/34] Generic support for TLS protocol & I/O channels Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 01/34] ui: remove check for failure of qemu_acl_init() Daniel P. Berrange
2015-04-17 15:56 ` Eric Blake
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 02/34] qom: document user creatable object types in help text Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 03/34] qom: create objects in two phases Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 04/34] qom: add object_new_propv / object_new_proplist constructors Daniel P. Berrange
2015-04-17 14:55 ` Paolo Bonzini
2015-04-17 15:16 ` Daniel P. Berrange
2015-04-17 16:11 ` Eric Blake
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 05/34] qom: make enum string tables const-correct Daniel P. Berrange
2015-04-17 14:56 ` Paolo Bonzini
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 06/34] qom: add a object_property_add_enum helper method Daniel P. Berrange
2015-04-17 14:56 ` Paolo Bonzini
2015-04-17 15:01 ` Paolo Bonzini
2015-04-17 15:11 ` Daniel P. Berrange
2015-04-17 15:19 ` Paolo Bonzini
2015-04-17 15:22 ` Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 07/34] qom: don't pass string table to object_get_enum method Daniel P. Berrange
2015-04-17 15:05 ` Paolo Bonzini
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 08/34] crypto: introduce new module for computing hash digests Daniel P. Berrange
2015-05-13 17:04 ` Daniel P. Berrange
2015-05-13 17:12 ` Paolo Bonzini
2015-05-13 17:21 ` Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 09/34] crypto: move built-in AES implementation into crypto/ Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 10/34] crypto: move built-in D3DES " Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 11/34] crypto: introduce generic cipher API & built-in implementation Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 12/34] crypto: add a gcrypt cipher implementation Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 13/34] crypto: add a nettle " Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 14/34] crypto: introduce new module for handling TLS credentials Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 15/34] crypto: add sanity checking of " Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 16/34] crypto: introduce new module for handling TLS sessions Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 17/34] block: convert quorum blockdrv to use crypto APIs Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 18/34] ui: convert VNC websockets " Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 19/34] block: convert qcow/qcow2 to use generic cipher API Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 20/34] ui: convert VNC " Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 21/34] io: add abstract QIOChannel classes Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 22/34] io: add helper module for creating watches on UNIX FDs Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 23/34] io: add QIOChannelSocket class Daniel P. Berrange
2015-04-17 15:28 ` Paolo Bonzini
2015-04-17 15:52 ` Daniel P. Berrange
2015-04-17 16:00 ` Paolo Bonzini
2015-04-20 7:18 ` Gerd Hoffmann
2015-04-23 12:31 ` Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 24/34] io: add QIOChannelFile class Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 25/34] io: add QIOTask class for async operations Daniel P. Berrange
2015-04-17 15:16 ` Paolo Bonzini
2015-04-17 15:49 ` Daniel P. Berrange
2015-04-17 15:57 ` Paolo Bonzini
2015-04-17 16:11 ` Daniel P. Berrange
2015-04-17 17:06 ` Paolo Bonzini
2015-04-17 17:38 ` Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 26/34] io: add QIOChannelTLS class Daniel P. Berrange
2015-04-17 14:22 ` Daniel P. Berrange [this message]
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 28/34] io: add QIOChannelWebsock class Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 29/34] ui: convert VNC server to use QEMUIOChannelSocket classes Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 30/34] ui: convert VNC server to use QIOChannelTLS Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 31/34] ui: convert VNC server to use QIOChannelWebsock Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 32/34] char: convert from GIOChannel to QIOChannel Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 33/34] char: don't assume telnet initialization will not block Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 34/34] char: introduce support for TLS encrypted TCP chardev backend Daniel P. Berrange
2015-04-17 18:27 ` Eric Blake
2015-04-23 12:32 ` Daniel P. Berrange
2015-05-04 20:07 ` Kashyap Chamarthy
2015-05-05 13:49 ` Daniel P. Berrange
2015-05-05 13:53 ` Paolo Bonzini
2015-05-05 13:56 ` Daniel P. Berrange
2015-05-05 14:54 ` Kashyap Chamarthy
2015-05-06 8:34 ` Kashyap Chamarthy
2015-05-06 10:18 ` Daniel P. Berrange
2015-05-06 11:38 ` Kashyap Chamarthy
2015-04-23 12:28 ` [Qemu-devel] [PATCH v1 RFC 00/34] Generic support for TLS protocol & I/O channels Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1429280557-8887-28-git-send-email-berrange@redhat.com \
--to=berrange@redhat.com \
--cc=kraxel@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.