summaryrefslogtreecommitdiff
path: root/usr.bin/tmux/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/tmux/buffer.c')
-rw-r--r--usr.bin/tmux/buffer.c227
1 files changed, 227 insertions, 0 deletions
diff --git a/usr.bin/tmux/buffer.c b/usr.bin/tmux/buffer.c
new file mode 100644
index 00000000000..7ff1b10efc0
--- /dev/null
+++ b/usr.bin/tmux/buffer.c
@@ -0,0 +1,227 @@
+/* $OpenBSD: buffer.c,v 1.1 2009/06/01 22:58:49 nicm Exp $ */
+
+/*
+ * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <string.h>
+
+#include "tmux.h"
+
+/* Create a buffer. */
+struct buffer *
+buffer_create(size_t size)
+{
+ struct buffer *b;
+
+ if (size == 0)
+ fatalx("zero size");
+
+ b = xcalloc(1, sizeof *b);
+
+ b->base = xmalloc(size);
+ b->space = size;
+
+ return (b);
+}
+
+/* Destroy a buffer. */
+void
+buffer_destroy(struct buffer *b)
+{
+ xfree(b->base);
+ xfree(b);
+}
+
+/* Empty a buffer. */
+void
+buffer_clear(struct buffer *b)
+{
+ b->size = 0;
+ b->off = 0;
+}
+
+/* Ensure free space for size in buffer. */
+void
+buffer_ensure(struct buffer *b, size_t size)
+{
+ if (size == 0)
+ fatalx("zero size");
+
+ if (BUFFER_FREE(b) >= size)
+ return;
+
+ if (b->off > 0) {
+ if (b->size > 0)
+ memmove(b->base, b->base + b->off, b->size);
+ b->off = 0;
+ }
+
+ if (SIZE_MAX - b->size < size)
+ fatalx("size too big");
+ while (b->space < b->size + size) {
+ b->base = xrealloc(b->base, 2, b->space);
+ b->space *= 2;
+ }
+}
+
+/* Adjust buffer after data appended. */
+void
+buffer_add(struct buffer *b, size_t size)
+{
+ if (size == 0)
+ fatalx("zero size");
+ if (size > b->space - b->size)
+ fatalx("overflow");
+
+ b->size += size;
+}
+
+/* Reverse buffer add. */
+void
+buffer_reverse_add(struct buffer *b, size_t size)
+{
+ if (size == 0)
+ fatalx("zero size");
+ if (size > b->size)
+ fatalx("underflow");
+
+ b->size -= size;
+}
+
+/* Adjust buffer after data removed. */
+void
+buffer_remove(struct buffer *b, size_t size)
+{
+ if (size == 0)
+ fatalx("zero size");
+ if (size > b->size)
+ fatalx("underflow");
+
+ b->size -= size;
+ b->off += size;
+}
+
+/* Reverse buffer remove. */
+void
+buffer_reverse_remove(struct buffer *b, size_t size)
+{
+ if (size == 0)
+ fatalx("zero size");
+ if (size > b->off)
+ fatalx("overflow");
+
+ b->size += size;
+ b->off -= size;
+}
+
+/* Insert a section into the buffer. */
+void
+buffer_insert_range(struct buffer *b, size_t base, size_t size)
+{
+ if (size == 0)
+ fatalx("zero size");
+ if (base > b->size)
+ fatalx("range outside buffer");
+
+ buffer_ensure(b, size);
+ memmove(b->base + b->off + base + size,
+ b->base + b->off + base, b->size - base);
+ b->size += size;
+}
+
+/* Delete a section from the buffer. */
+void
+buffer_delete_range(struct buffer *b, size_t base, size_t size)
+{
+ if (size == 0)
+ fatalx("zero size");
+ if (size > b->size)
+ fatalx("size too big");
+ if (base + size > b->size)
+ fatalx("range outside buffer");
+
+ memmove(b->base + b->off + base,
+ b->base + b->off + base + size, b->size - base - size);
+ b->size -= size;
+}
+
+/* Copy data into a buffer. */
+void
+buffer_write(struct buffer *b, const void *data, size_t size)
+{
+ if (size == 0)
+ fatalx("zero size");
+
+ buffer_ensure(b, size);
+ memcpy(BUFFER_IN(b), data, size);
+ buffer_add(b, size);
+}
+
+/* Copy data out of a buffer. */
+void
+buffer_read(struct buffer *b, void *data, size_t size)
+{
+ if (size == 0)
+ fatalx("zero size");
+ if (size > b->size)
+ fatalx("underflow");
+
+ memcpy(data, BUFFER_OUT(b), size);
+ buffer_remove(b, size);
+}
+
+/* Store an 8-bit value. */
+void
+buffer_write8(struct buffer *b, uint8_t n)
+{
+ buffer_ensure(b, 1);
+ BUFFER_IN(b)[0] = n;
+ buffer_add(b, 1);
+}
+
+/* Store a 16-bit value. */
+void
+buffer_write16(struct buffer *b, uint16_t n)
+{
+ buffer_ensure(b, 2);
+ BUFFER_IN(b)[0] = n & 0xff;
+ BUFFER_IN(b)[1] = n >> 8;
+ buffer_add(b, 2);
+}
+
+/* Extract an 8-bit value. */
+uint8_t
+buffer_read8(struct buffer *b)
+{
+ uint8_t n;
+
+ n = BUFFER_OUT(b)[0];
+ buffer_remove(b, 1);
+ return (n);
+}
+
+/* Extract a 16-bit value. */
+uint16_t
+buffer_read16(struct buffer *b)
+{
+ uint16_t n;
+
+ n = BUFFER_OUT(b)[0] | (BUFFER_OUT(b)[1] << 8);
+ buffer_remove(b, 2);
+ return (n);
+}