18static char SccsId[] =
"%W% %G%";
28#if !HAVE_FMEMOPEN || !defined(HAVE_FMEMOPEN)
30#include "YapStreams.h"
34int format_synch(
int sno,
int sno0,
format_info *fg) {
35 int (*f_putc)(int, int);
41 f_putc = GLOBAL_Stream[sno0].stream_putc;
42 s = GLOBAL_Stream[sno].u.mem_string.buf;
43 n = GLOBAL_Stream[sno].u.mem_string.pos;
47 GLOBAL_Stream[sno].u.mem_string.pos = 0;
48 GLOBAL_Stream[sno].linecount = 1;
49 GLOBAL_Stream[sno].linepos = 0;
50 GLOBAL_Stream[sno].charcount = 0;
51 GLOBAL_Stream[sno].vfs = NULL;
59bool fill_pads(
int sno,
int sno0,
int total,
format_info *fg USES_REGS) {
60 int nfillers, fill_space, lfill_space, nchars;
61 int (*f_putc)(int, int);
65 f_putc = GLOBAL_Stream[sno0].stream_putc;
66 buf = GLOBAL_Stream[sno].u.mem_string.buf;
67 phys_end = GLOBAL_Stream[sno].u.mem_string.pos;
69 fg->gap[0].phys = phys_end;
70 fg->gap[0].filler =
' ';
73 nchars = total - GLOBAL_Stream[sno].linepos;
77 fill_space = nchars / nfillers;
78 lfill_space = nchars % nfillers;
80 int i = fg->phys_start;
81 gap_t *padi = fg->gap;
82 while (i < phys_end) {
83 if (i == padi->phys) {
85 for (j = 0; j < fill_space; j++)
86 f_putc(sno0, padi->filler);
89 if (padi - fg->gap == fg->gapi) {
90 for (j = 0; j < fill_space; j++)
91 f_putc(sno0, (padi - 1)->filler);
94 f_putc(sno0, buf[i++]);
97 if (i == padi->phys) {
99 for (j = 0; j < fill_space + lfill_space; j++)
100 f_putc(sno0, padi->filler);
103 GLOBAL_Stream[sno].u.mem_string.pos = 0;
104 GLOBAL_Stream[sno].linecount = 1;
105 GLOBAL_Stream[sno].linepos += 0;
106 GLOBAL_Stream[sno].charcount = nchars;
107 GLOBAL_Stream[sno].vfs = NULL;
108 GLOBAL_Stream[sno].file = NULL;
110 fg->lstart = GLOBAL_Stream[sno].linepos;
116static int MemGetc(
int sno) {
121 spos = s->u.mem_string.pos;
122 if (spos == s->u.mem_string.max_size) {
125 ch = s->u.mem_string.buf[spos];
126 s->u.mem_string.pos = ++spos;
132int Yap_MemPeekc(
int sno) {
137 spos = s->u.mem_string.pos;
138 if (spos == s->u.mem_string.max_size) {
141 ch = s->u.mem_string.buf[spos];
146static int MemPutc(
int,
int);
149static int MemPutc(
int sno,
int ch) {
156 s->u.mem_string.buf[s->u.mem_string.pos++] = ch;
157 if (s->u.mem_string.pos >= s->u.mem_string.max_size - 8) {
161 Int new_max_size = s->u.mem_string.max_size + Yap_page_size;
163 if ((newbuf = (ADDR)realloc(s->u.mem_string.buf,
164 new_max_size *
sizeof(
char))) != NULL) {
165 new_src = MEM_BUF_MALLOC;
167 if (GLOBAL_Stream[sno].u.mem_string.error_handler) {
169 LOCAL_Error_Size = new_max_size *
sizeof(char);
171 longjmp(*(jmp_buf *)GLOBAL_Stream[sno].u.mem_string.error_handler, 1);
173 Yap_Error(RESOURCE_ERROR_HEAP, TermNil,
174 "YAP could not grow heap for writing to string");
178 s->u.mem_string.buf = newbuf;
179 s->u.mem_string.max_size = new_max_size;
180 s->u.mem_string.src = new_src;
182 count_output_char(ch, s);
186bool Yap_set_stream_to_buf(
StreamDesc *st,
const char *buf,
187 size_t nchars USES_REGS) {
189 stream_flags_t flags;
192 flags = Input_Stream_f | InMemory_Stream_f;
194 Yap_initStream(st - GLOBAL_Stream, f, Yap_LookupAtom(
"buffer"),
"r", TermNil, LOCAL_encoding, flags, NULL);
197 st->status = Input_Stream_f | InMemory_Stream_f;
198 st->u.mem_string.pos = 0;
199 st->u.mem_string.buf = (
char *)buf;
200 st->u.mem_string.max_size = nchars;
201 st->u.mem_string.error_handler = NULL;
203 Yap_DefaultStreamOps(st);
207int Yap_open_buf_read_stream(
const char *buf,
size_t nchars, encoding_t *encp, memBufSource src ,
Atom name, Term uname) {
213 stream_flags_t flags;
215 sno = GetFreeStreamD();
217 return (PlIOError(RESOURCE_ERROR_MAX_STREAMS, TermNil,
218 "new stream not available for open_mem_read_stream/1"));
219 st = GLOBAL_Stream + sno;
225 flags = Input_Stream_f | InMemory_Stream_f;
228 Yap_initStream(sno, f, Yap_LookupAtom(
"Memory Stream"),
"wa", TermNil,
encoding, flags, NULL);
231 st->status = Input_Stream_f | InMemory_Stream_f;
232 st->u.mem_string.pos = 0;
233 st->u.mem_string.buf = (
char *)buf;
234 st->u.mem_string.max_size = nchars;
235 st->u.mem_string.error_handler = NULL;
236 st->u.mem_string.src = src;
237 Yap_DefaultStreamOps(st);
238 UNLOCK(st->streamlock);
243open_mem_read_stream(USES_REGS1)
247 int i = push_text_stack();
251 buf = Yap_TextTermToText(ti PASS_REGS);
255 buf = pop_output_text_stack(i, buf);
256 sno = Yap_open_buf_read_stream(buf, strlen(buf) + 1, &LOCAL_encoding,
257 MEM_BUF_MALLOC, AtomNil, TermNil);
258 t = Yap_MkStream(sno);
259 return Yap_unify(ARG2, t);
264int Yap_open_buf_write_stream(encoding_t enc, memBufSource src) {
269 sno = GetFreeStreamD();
272 st = GLOBAL_Stream + sno;
273 st->status = Output_Stream_f | InMemory_Stream_f | FreeOnClose_Stream_f;
280 Yap_DefaultStreamOps(st);
281 st->nbuf = st->u.mem_string.buf = malloc(PLGETC_BUF_SIZE);
282 st->u.mem_string.src = MEM_BUF_MALLOC;
283 st->u.mem_string.max_size = PLGETC_BUF_SIZE - 1;
284 st->u.mem_string.pos = 0;
285 UNLOCK(st->streamlock);
289int Yap_OpenBufWriteStream(USES_REGS1) {
291 return Yap_open_buf_write_stream(
292 GLOBAL_Stream[LOCAL_c_output_stream].
encoding, 0);
296open_mem_write_stream(USES_REGS1)
301 sno = Yap_OpenBufWriteStream(PASS_REGS1);
303 return (PlIOError(SYSTEM_ERROR_INTERNAL, TermNil,
304 "new stream not available for open_mem_read_stream/1"));
305 t = Yap_MkStream(sno);
306 GLOBAL_Stream[sno].status |= InMemory_Stream_f;
307 return (Yap_unify(ARG1, t));
318char *Yap_MemExportStreamPtr(
int sno) {
320 GLOBAL_Stream[sno].u.mem_string.buf[GLOBAL_Stream[sno].u.mem_string.pos] =
322 return GLOBAL_Stream[sno].u.mem_string.buf;
325static Int peek_mem_write_stream(
328 Yap_CheckStream(ARG1, (Output_Stream_f | InMemory_Stream_f),
"close/2");
338 ptr = GLOBAL_Stream[sno].u.mem_string.buf;
339 i = GLOBAL_Stream[sno].u.mem_string.pos;
342 tf = MkPairTerm(MkIntTerm(ptr[i]), tf);
343 if (HR + 1024 >= ASP) {
344 UNLOCK(GLOBAL_Stream[sno].streamlock);
346 if (!Yap_gcl((ASP - HI) *
sizeof(CELL), 3, ENV, Yap_gcP())) {
347 UNLOCK(GLOBAL_Stream[sno].streamlock);
348 Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
351 i = GLOBAL_Stream[sno].u.mem_string.pos;
353 LOCK(GLOBAL_Stream[sno].streamlock);
357 UNLOCK(GLOBAL_Stream[sno].streamlock);
358 return (Yap_unify(ARG3, tf));
362 st->stream_putc = MemPutc;
367bool Yap_CloseMemoryStream(
int sno) {
368 if ((GLOBAL_Stream[sno].status & Output_Stream_f)) {
369 if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_MALLOC) {
370 free(GLOBAL_Stream[sno].u.mem_string.buf);
373 if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_MALLOC) {
374 free(GLOBAL_Stream[sno].u.mem_string.buf);
380void Yap_InitMems(
void) {
382 Yap_InitCPred(
"open_mem_read_stream", 2, open_mem_read_stream, SyncPredFlag);
383 Yap_InitCPred(
"open_mem_write_stream", 1, open_mem_write_stream,
385 Yap_InitCPred(
"peek_mem_write_stream", 3, peek_mem_write_stream,
@ encoding
support for coding systens, YAP relies on UTF-8 internally
int(* stream_getc)(int)
function the stream uses for writing a character
encoding_t encoding
check if the next wide character is available
struct vfs * vfs
function the stream uses for reading a character