klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit b63dc958796904765e512a928e06ff0282e4f401
parent 80f6c37599fc6090074e3fc0ee155390b4cc160e
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Fri, 18 Nov 2011 16:01:16 -0300

Added a function to grow the internal buffer of bytevector and string output ports.

Diffstat:
Msrc/kobject.h | 2+-
Msrc/kport.c | 43+++++++++++++++++++++++++++++++++++++++++++
Msrc/kport.h | 2++
3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/src/kobject.h b/src/kobject.h @@ -463,7 +463,7 @@ typedef struct __attribute__ ((__packed__)) { CommonHeader; PortCommonFields; TValue buf; - int32_t off; + uint32_t off; } MPort; diff --git a/src/kport.c b/src/kport.c @@ -6,6 +6,7 @@ #include <stdio.h> #include <assert.h> +#include <string.h> #include "kport.h" #include "kobject.h" @@ -184,3 +185,45 @@ void kport_update_source_info(TValue port, int32_t line, int32_t col) kport_line(port) = line; kport_col(port) = col; } + +/* Always grow by doubling the size (until min_size is reached) */ +/* GC: port should be rooted */ +void kmport_resize_buffer(klisp_State *K, TValue port, size_t min_size) +{ + klisp_assert(ttismport(port)); + klisp_assert(kport_is_output(port)); + + uint32_t old_size = (kport_is_binary(port))? + kbytevector_size(kmport_buf(port)) : + kstring_size(kmport_buf(port)); + uint64_t new_size = old_size; + + while (new_size < min_size) { + new_size *= 2; + if (new_size > SIZE_MAX) + klispM_toobig(K); + } + + if (new_size == old_size) + return; + + if (kport_is_binary(port)) { + TValue new_bb = kbytevector_new_s(K, new_size); + uint32_t off = kmport_off(port); + if (off != 0) { + memcpy(kbytevector_buf(new_bb), + kbytevector_buf(kmport_buf(port)), + off); + } + kmport_buf(port) = new_bb; + } else { + TValue new_str = kstring_new_s(K, new_size); + uint32_t off = kmport_off(port); + if (off != 0) { + memcpy(kstring_buf(new_str), + kstring_buf(kmport_buf(port)), + off); + } + kmport_buf(port) = new_str; + } +} diff --git a/src/kport.h b/src/kport.h @@ -54,5 +54,7 @@ void kclose_port(klisp_State *K, TValue port); void kport_reset_source_info(TValue port); void kport_update_source_info(TValue port, int32_t line, int32_t col); +/* GC: port should be rooted */ +void kmport_resize_buffer(klisp_State *K, TValue port, uint32_t min_size); #endif