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:
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