From fce6f43f7af9500373605ac718d8765c7fa1c022 Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Thu, 25 Aug 2016 23:38:09 -0400 Subject: [PATCH] Initial file --- mem-streams.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 mem-streams.c diff --git a/mem-streams.c b/mem-streams.c new file mode 100644 index 00000000..8bd339a9 --- /dev/null +++ b/mem-streams.c @@ -0,0 +1,91 @@ +/** + * Cyclone Scheme + * https://github.com/justinethier/cyclone + * + * Copyright (c) 2014-2016, Justin Ethier + * All rights reserved. + * + * This file contains platform-specific code for memory streams. + */ + +#include "cyclone/types.h" +#include "cyclone/runtime.h" +#include +//#include +//#include + +/* These macros are hardcoded here to support functions in this module. */ +#define closcall1(td, clo, a1) \ +if (type_is_pair_prim(clo)) { \ + Cyc_apply(td, 0, (closure)(a1), clo); \ +} else { \ + ((clo)->fn)(td, 1, clo, a1);\ +} +#define return_closcall1(td, clo, a1) { \ + char top; \ + if (stack_overflow(&top, (((gc_thread_data *)data)->stack_limit))) { \ + object buf[1]; buf[0] = a1;\ + GC(td, clo, buf, 1); \ + return; \ + } else {\ + closcall1(td, (closure) (clo), a1); \ + return;\ + } \ +} + +port_type Cyc_io_open_output_string(void *data) +{ + make_port(p, NULL, 0); + errno = 0; + p.fp = open_memstream(&(p.mem_buf), &(p.mem_buf_len)); + if (p.fp == NULL){ + Cyc_rt_raise2(data, "Unable to open memory stream", obj_int2obj(errno)); + } + return p; +} + +void Cyc_io_get_output_string(void *data, object cont, object port) +{ + Cyc_check_port(data, port); + if (((port_type *)port)->mem_buf == NULL) { + Cyc_rt_raise2(data, "Not an in-memory port", port); + } + { + port_type *p = (port_type *)port; + make_string_with_len(s, p->mem_buf, p->mem_buf_len); + return_closcall1(data, cont, &s); + } +} + +// TODO: when closing a memory port, need to free mem_buf if != NULL + + +// Hacky approach to a minimal string buffer implementation. This may change in the future +// For background see: http://stackoverflow.com/questions/539537/memory-buffer-as-file +//port_type Cyc_io_open_output_string(void *data) +// +//// TODO: no, this is too hacky. fuck it, just use fmemopen or open_memstream +//// for non-supported platforms we'll raise an error and not do anything +//{ +// FILE *f = fopen("/dev/null", "w"); +// int i; +// int written = 0; +// char *buf = malloc(100000); +// make_port(p, NULL, 0); // TODO: probably wrong params, need to add buf to port obj and type +// //setbuffer(f, buf, 100000); +// if (0 != setvbuf (f, buf, _IOFBF, 100000)){ +// // TODO: raise() instead? +// fprintf(stderr, "Unable to setvbuf!\n"); +// exit(1); +// } +// for (i = 0; i < 1000; i++) { +// written += fprintf(f, "Number %d\n", i); +// } +// for (i = 0; i < written; i++) { +// printf("%c", buf[i]); +// } +// return p; +//} +// +//// END string buffers +