From 66c3f91b14e24510319bce6b5cc2fecf8cf5abff Mon Sep 17 00:00:00 2001 From: nsf Date: Sat, 3 Aug 2013 17:36:04 +0600 Subject: [PATCH] Replace memstream with bytebuffer. --- src/bytebuffer.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ src/bytebuffer.h | 17 ++++++++++++ src/memstream.c | 27 ------------------- src/memstream.h | 19 -------------- src/termbox.c | 53 +++++++++++++++++++------------------- 5 files changed, 110 insertions(+), 73 deletions(-) create mode 100644 src/bytebuffer.c create mode 100644 src/bytebuffer.h delete mode 100644 src/memstream.c delete mode 100644 src/memstream.h diff --git a/src/bytebuffer.c b/src/bytebuffer.c new file mode 100644 index 0000000..80a0e13 --- /dev/null +++ b/src/bytebuffer.c @@ -0,0 +1,67 @@ +#include "bytebuffer.h" +#include +#include +#include + +static void bytebuffer_reserve(struct bytebuffer *b, int cap) { + if (b->cap >= cap) { + return; + } + + // prefer doubling capacity + if (b->cap * 2 >= cap) { + cap = b->cap * 2; + } + + char *newbuf = malloc(cap); + if (b->len > 0) { + // copy what was there, b->len > 0 assumes b->buf != null + memcpy(newbuf, b->buf, b->len); + } + if (b->buf) { + // in case there was an allocated buffer, free it + free(b->buf); + } + b->buf = newbuf; + b->cap = cap; +} + +void init_bytebuffer(struct bytebuffer *b, int cap) { + b->cap = 0; + b->len = 0; + b->buf = 0; + + if (cap > 0) { + b->cap = cap; + b->buf = malloc(cap); // just assume malloc works always + } +} + +void free_bytebuffer(struct bytebuffer *b) { + if (b->buf) + free(b->buf); +} + +void clear_bytebuffer(struct bytebuffer *b) { + b->len = 0; +} + +void bytebuffer_puts(struct bytebuffer *b, const char *str) { + bytebuffer_append(b, str, strlen(str)); +} + +void bytebuffer_append(struct bytebuffer *b, const char *data, int len) { + bytebuffer_reserve(b, b->len + len); + memcpy(b->buf + b->len, data, len); + b->len += len; +} + +void resize_bytebuffer(struct bytebuffer *b, int len) { + bytebuffer_reserve(b, len); + b->len = len; +} + +void flush_bytebuffer(struct bytebuffer *b, int fd) { + write(fd, b->buf, b->len); + clear_bytebuffer(b); +} diff --git a/src/bytebuffer.h b/src/bytebuffer.h new file mode 100644 index 0000000..ccbc685 --- /dev/null +++ b/src/bytebuffer.h @@ -0,0 +1,17 @@ +#pragma once + +struct bytebuffer { + char *buf; + int len; + int cap; +}; + +void init_bytebuffer(struct bytebuffer *b, int cap); +void free_bytebuffer(struct bytebuffer *b); +void clear_bytebuffer(struct bytebuffer *b); +void resize_bytebuffer(struct bytebuffer *b, int len); +void bytebuffer_puts(struct bytebuffer *b, const char *str); +void bytebuffer_append(struct bytebuffer *b, const char *data, int len); + +// writes the contents of the buffer to the given fd and then clears the buffer +void flush_bytebuffer(struct bytebuffer *b, int fd); diff --git a/src/memstream.c b/src/memstream.c deleted file mode 100644 index 5dea7b2..0000000 --- a/src/memstream.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include "memstream.h" - -void memstream_init(struct memstream *s, int fd, void* buffer, size_t len) { - s->file = fd, - s->data = buffer; - s->pos = 0; - s->capa = len; -} - -void memstream_flush(struct memstream *s) { - write(s->file, s->data, s->pos); - s->pos = 0; -} - -void memstream_write(struct memstream *s, void* source, size_t len) { - unsigned char* data = source; - if(s->pos + len > s->capa) memstream_flush(s); - memcpy(s->data + s->pos, data, len); - s->pos += len; -} - -void memstream_puts(struct memstream *s, const char* str) { - memstream_write(s, (void*) str, strlen(str)); -} diff --git a/src/memstream.h b/src/memstream.h deleted file mode 100644 index 306df8f..0000000 --- a/src/memstream.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef MEMSTREAM_H -#define MEMSTREAM_H - -#include -#include - -struct memstream { - size_t pos; - size_t capa; - int file; - unsigned char* data; -}; - -void memstream_init(struct memstream *s, int fd, void* buffer, size_t len); -void memstream_flush(struct memstream *s); -void memstream_write(struct memstream *s, void* source, size_t len); -void memstream_puts(struct memstream *s, const char* str); - -#endif diff --git a/src/termbox.c b/src/termbox.c index 0137933..a230f5a 100644 --- a/src/termbox.c +++ b/src/termbox.c @@ -12,7 +12,7 @@ #include "term.h" #include "termbox.h" -#include "memstream.h" +#include "bytebuffer.h" struct cellbuf { unsigned int width; @@ -29,8 +29,7 @@ static struct termios orig_tios; static struct cellbuf back_buffer; static struct cellbuf front_buffer; -static unsigned char write_buffer_data[32 * 1024]; -static struct memstream write_buffer; +static struct bytebuffer output_buffer; static unsigned int termw; static unsigned int termh; @@ -128,11 +127,11 @@ int tb_init(void) tios.c_cc[VTIME] = 0; tcsetattr(out_fileno, TCSAFLUSH, &tios); - memstream_init(&write_buffer, out_fileno, write_buffer_data, sizeof(write_buffer_data)); + init_bytebuffer(&output_buffer, 32 * 1024); - memstream_puts(&write_buffer, funcs[T_ENTER_CA]); - memstream_puts(&write_buffer, funcs[T_ENTER_KEYPAD]); - memstream_puts(&write_buffer, funcs[T_HIDE_CURSOR]); + bytebuffer_puts(&output_buffer, funcs[T_ENTER_CA]); + bytebuffer_puts(&output_buffer, funcs[T_ENTER_KEYPAD]); + bytebuffer_puts(&output_buffer, funcs[T_HIDE_CURSOR]); send_clear(); update_term_size(); @@ -147,12 +146,12 @@ int tb_init(void) void tb_shutdown(void) { - memstream_puts(&write_buffer, funcs[T_SHOW_CURSOR]); - memstream_puts(&write_buffer, funcs[T_SGR0]); - memstream_puts(&write_buffer, funcs[T_CLEAR_SCREEN]); - memstream_puts(&write_buffer, funcs[T_EXIT_CA]); - memstream_puts(&write_buffer, funcs[T_EXIT_KEYPAD]); - memstream_flush(&write_buffer); + bytebuffer_puts(&output_buffer, funcs[T_SHOW_CURSOR]); + bytebuffer_puts(&output_buffer, funcs[T_SGR0]); + bytebuffer_puts(&output_buffer, funcs[T_CLEAR_SCREEN]); + bytebuffer_puts(&output_buffer, funcs[T_EXIT_CA]); + bytebuffer_puts(&output_buffer, funcs[T_EXIT_KEYPAD]); + flush_bytebuffer(&output_buffer, out_fileno); tcsetattr(out_fileno, TCSAFLUSH, &orig_tios); shutdown_term(); @@ -193,16 +192,16 @@ void tb_present(void) } if (!IS_CURSOR_HIDDEN(cursor_x, cursor_y)) write_cursor(cursor_x, cursor_y); - memstream_flush(&write_buffer); + flush_bytebuffer(&output_buffer, out_fileno); } void tb_set_cursor(int cx, int cy) { if (IS_CURSOR_HIDDEN(cursor_x, cursor_y) && !IS_CURSOR_HIDDEN(cx, cy)) - memstream_puts(&write_buffer, funcs[T_SHOW_CURSOR]); + bytebuffer_puts(&output_buffer, funcs[T_SHOW_CURSOR]); if (!IS_CURSOR_HIDDEN(cursor_x, cursor_y) && IS_CURSOR_HIDDEN(cx, cy)) - memstream_puts(&write_buffer, funcs[T_HIDE_CURSOR]); + bytebuffer_puts(&output_buffer, funcs[T_HIDE_CURSOR]); cursor_x = cx; cursor_y = cy; @@ -286,8 +285,8 @@ void tb_set_clear_attributes(uint16_t fg, uint16_t bg) /* -------------------------------------------------------- */ -static unsigned convertnum(uint32_t num, char* buf) { - unsigned i, l = 0; +static int convertnum(uint32_t num, char* buf) { + int i, l = 0; int ch; do { buf[l++] = '0' + (num % 10); @@ -301,8 +300,8 @@ static unsigned convertnum(uint32_t num, char* buf) { return l; } -#define WRITE_LITERAL(X) memstream_write(&write_buffer, (X), sizeof(X) -1) -#define WRITE_INT(X) memstream_write(&write_buffer, buf, convertnum((X), buf)) +#define WRITE_LITERAL(X) bytebuffer_append(&output_buffer, (X), sizeof(X)-1) +#define WRITE_INT(X) bytebuffer_append(&output_buffer, buf, convertnum((X), buf)) static void write_cursor(unsigned x, unsigned y) { char buf[32]; @@ -414,14 +413,14 @@ static void send_attr(uint16_t fg, uint16_t bg) #define LAST_ATTR_INIT 0xFFFF static uint16_t lastfg = LAST_ATTR_INIT, lastbg = LAST_ATTR_INIT; if (fg != lastfg || bg != lastbg) { - memstream_puts(&write_buffer, funcs[T_SGR0]); + bytebuffer_puts(&output_buffer, funcs[T_SGR0]); write_sgr(fg & 0x0F, bg & 0x0F); if (fg & TB_BOLD) - memstream_puts(&write_buffer, funcs[T_BOLD]); + bytebuffer_puts(&output_buffer, funcs[T_BOLD]); if (bg & TB_BOLD) - memstream_puts(&write_buffer, funcs[T_BLINK]); + bytebuffer_puts(&output_buffer, funcs[T_BLINK]); if (fg & TB_UNDERLINE) - memstream_puts(&write_buffer, funcs[T_UNDERLINE]); + bytebuffer_puts(&output_buffer, funcs[T_UNDERLINE]); lastfg = fg; lastbg = bg; @@ -437,16 +436,16 @@ static void send_char(unsigned int x, unsigned int y, uint32_t c) write_cursor(x, y); lastx = x; lasty = y; if(!c) buf[0] = ' '; // replace 0 with whitespace - memstream_puts(&write_buffer, buf); + bytebuffer_puts(&output_buffer, buf); } static void send_clear(void) { send_attr(foreground, background); - memstream_puts(&write_buffer, funcs[T_CLEAR_SCREEN]); + bytebuffer_puts(&output_buffer, funcs[T_CLEAR_SCREEN]); if (!IS_CURSOR_HIDDEN(cursor_x, cursor_y)) write_cursor(cursor_x, cursor_y); - memstream_flush(&write_buffer); + flush_bytebuffer(&output_buffer, out_fileno); /* we need to invalidate cursor position too and these two vars are * used only for simple cursor positioning optimization, cursor