| 
									
										
										
										
											2016-02-28 19:32:55 +00:00
										 |  |  | /*************************************************************************
 | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | *									 * | 
					
						
							|  |  |  | *	 YAP Prolog 							 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | *	Yap Prolog was developed at NCCUP - Universidade do Porto	 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997	 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | ************************************************************************** | 
					
						
							|  |  |  | *									 * | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  | * File:		mem.c * | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | * Last rev:	5/2/88							 * | 
					
						
							|  |  |  | * mods:									 * | 
					
						
							|  |  |  | * comments:	Input/Output C implemented predicates			 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | *************************************************************************/ | 
					
						
							|  |  |  | #ifdef SCCS
 | 
					
						
							|  |  |  | static char SccsId[] = "%W% %G%"; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * This file includes the definition of a socket related IO. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-08 01:22:27 -07:00
										 |  |  | #include "sysbits.h"
 | 
					
						
							| 
									
										
										
										
											2016-01-31 10:02:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 19:32:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if !HAVE_FMEMOPEN || !defined(HAVE_FMEMOPEN)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "format.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 09:08:22 -05:00
										 |  |  | int format_synch(int sno, int sno0, format_info *fg) { | 
					
						
							| 
									
										
										
										
											2016-09-27 19:32:27 -05:00
										 |  |  |   int (*f_putc)(int, int); | 
					
						
							|  |  |  |   const char *s; | 
					
						
							|  |  |  |   int n; | 
					
						
							|  |  |  |   if (sno == sno0) { | 
					
						
							| 
									
										
										
										
											2016-09-28 09:08:22 -05:00
										 |  |  |     return sno; | 
					
						
							| 
									
										
										
										
											2016-09-27 19:32:27 -05:00
										 |  |  |   } | 
					
						
							|  |  |  |   f_putc = GLOBAL_Stream[sno0].stream_putc; | 
					
						
							|  |  |  |   s = GLOBAL_Stream[sno].u.mem_string.buf; | 
					
						
							|  |  |  |   n = GLOBAL_Stream[sno].u.mem_string.pos; | 
					
						
							|  |  |  |   while (n--) { | 
					
						
							|  |  |  |     f_putc(sno0, *s++); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   GLOBAL_Stream[sno].u.mem_string.pos = 0; | 
					
						
							|  |  |  |   GLOBAL_Stream[sno].linecount = 1; | 
					
						
							|  |  |  |   GLOBAL_Stream[sno].linepos = 0; | 
					
						
							|  |  |  |   GLOBAL_Stream[sno].charcount = 0; | 
					
						
							|  |  |  |   fg->lstart = 0; | 
					
						
							|  |  |  |   fg->phys_start = 0; | 
					
						
							|  |  |  |   fg->gapi = 0; | 
					
						
							| 
									
										
										
										
											2016-09-28 09:08:22 -05:00
										 |  |  |   return sno; | 
					
						
							| 
									
										
										
										
											2016-09-27 19:32:27 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // uses directly the buffer in the memory stream.
 | 
					
						
							|  |  |  |  bool fill_pads(int sno, int sno0, int total, format_info *fg USES_REGS) { | 
					
						
							|  |  |  |   int nfillers, fill_space, lfill_space, nchars; | 
					
						
							|  |  |  |   int (*f_putc)(int, int); | 
					
						
							|  |  |  |   const char *buf; | 
					
						
							|  |  |  |   int phys_end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   f_putc = GLOBAL_Stream[sno0].stream_putc; | 
					
						
							|  |  |  |   buf = GLOBAL_Stream[sno].u.mem_string.buf; | 
					
						
							|  |  |  |   phys_end = GLOBAL_Stream[sno].u.mem_string.pos; | 
					
						
							|  |  |  |   if (fg->gapi == 0) { | 
					
						
							|  |  |  |     fg->gap[0].phys = phys_end; | 
					
						
							|  |  |  |     fg->gap[0].filler = ' '; | 
					
						
							|  |  |  |     fg->gapi = 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   nchars = total - GLOBAL_Stream[sno].linepos; | 
					
						
							|  |  |  |   if (nchars < 0) | 
					
						
							|  |  |  |     nchars = 0; /* ignore */ | 
					
						
							|  |  |  |   nfillers = fg->gapi; | 
					
						
							|  |  |  |   fill_space = nchars / nfillers; | 
					
						
							|  |  |  |   lfill_space = nchars % nfillers; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int i = fg->phys_start; | 
					
						
							|  |  |  |   gap_t *padi = fg->gap; | 
					
						
							|  |  |  |   while (i < phys_end) { | 
					
						
							|  |  |  |     if (i == padi->phys) { | 
					
						
							|  |  |  |       int j; | 
					
						
							|  |  |  |       for (j = 0; j < fill_space; j++) | 
					
						
							|  |  |  |         f_putc(sno0, padi->filler); | 
					
						
							|  |  |  |       padi++; | 
					
						
							|  |  |  |       /* last gap??*/ | 
					
						
							|  |  |  |       if (padi - fg->gap == fg->gapi) { | 
					
						
							|  |  |  |         for (j = 0; j < fill_space; j++) | 
					
						
							|  |  |  |           f_putc(sno0, (padi - 1)->filler); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     f_putc(sno0, buf[i++]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // final gap
 | 
					
						
							|  |  |  |   if (i == padi->phys) { | 
					
						
							|  |  |  |     int j; | 
					
						
							|  |  |  |     for (j = 0; j < fill_space + lfill_space; j++) | 
					
						
							|  |  |  |       f_putc(sno0, padi->filler); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GLOBAL_Stream[sno].u.mem_string.pos = 0; | 
					
						
							|  |  |  |   GLOBAL_Stream[sno].linecount = 1; | 
					
						
							|  |  |  |   GLOBAL_Stream[sno].linepos += nchars; | 
					
						
							|  |  |  |   GLOBAL_Stream[sno].charcount = 0; | 
					
						
							|  |  |  |   fg->phys_start = 0; | 
					
						
							|  |  |  |   fg->lstart = GLOBAL_Stream[sno].linepos; | 
					
						
							|  |  |  |   fg->gapi = 0; | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* read from memory */ | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | static int MemGetc(int sno) { | 
					
						
							|  |  |  |   register StreamDesc *s = &GLOBAL_Stream[sno]; | 
					
						
							|  |  |  |   Int ch; | 
					
						
							|  |  |  |   int spos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   spos = s->u.mem_string.pos; | 
					
						
							|  |  |  |   if (spos == s->u.mem_string.max_size) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     ch = s->u.mem_string.buf[spos]; | 
					
						
							|  |  |  |     s->u.mem_string.pos = ++spos; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return ch; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* peek from memory */ | 
					
						
							|  |  |  | int Yap_MemPeekc(int sno) { | 
					
						
							|  |  |  |   StreamDesc *s = &GLOBAL_Stream[sno]; | 
					
						
							|  |  |  |   Int ch; | 
					
						
							|  |  |  |   int spos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   spos = s->u.mem_string.pos; | 
					
						
							|  |  |  |   if (spos == s->u.mem_string.max_size) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     ch = s->u.mem_string.buf[spos]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return ch; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | static int MemPutc(int, int); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* static */ | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | static int MemPutc(int sno, int ch) { | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |   StreamDesc *s = &GLOBAL_Stream[sno]; | 
					
						
							|  |  |  | #if MAC || _MSC_VER
 | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   if (ch == 10) { | 
					
						
							|  |  |  |     ch = '\n'; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   s->u.mem_string.buf[s->u.mem_string.pos++] = ch; | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   if (s->u.mem_string.pos >= s->u.mem_string.max_size - 8) { | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |     int new_src; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* oops, we have reached an overflow */ | 
					
						
							|  |  |  |     Int new_max_size = s->u.mem_string.max_size + Yap_page_size; | 
					
						
							|  |  |  |     char *newbuf; | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |     if ((newbuf = (ADDR)realloc(s->u.mem_string.buf, | 
					
						
							|  |  |  |                                 new_max_size * sizeof(char))) != NULL) { | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |       new_src = MEM_BUF_MALLOC; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       if (GLOBAL_Stream[sno].u.mem_string.error_handler) { | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |         CACHE_REGS | 
					
						
							|  |  |  |         LOCAL_Error_Size = new_max_size * sizeof(char); | 
					
						
							|  |  |  |         save_machine_regs(); | 
					
						
							|  |  |  |         longjmp(*(jmp_buf *)GLOBAL_Stream[sno].u.mem_string.error_handler, 1); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |         Yap_Error(RESOURCE_ERROR_HEAP, TermNil, | 
					
						
							|  |  |  |                   "YAP could not grow heap for writing to string"); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     s->u.mem_string.buf = newbuf; | 
					
						
							|  |  |  |     s->u.mem_string.max_size = new_max_size; | 
					
						
							|  |  |  |     s->u.mem_string.src = new_src; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   count_output_char(ch, s); | 
					
						
							|  |  |  |   return ((int)ch); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  | bool Yap_set_stream_to_buf(StreamDesc *st, const char *buf, size_t nchars) { | 
					
						
							|  |  |  |   FILE *f; | 
					
						
							|  |  |  |   stream_flags_t flags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   st->file = f = NULL; | 
					
						
							|  |  |  |   flags = Input_Stream_f | InMemory_Stream_f; | 
					
						
							| 
									
										
										
										
											2017-06-05 13:06:12 +01:00
										 |  |  |   st->vfs = NULL; | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |   Yap_initStream(st - GLOBAL_Stream, f, NULL, TermNil, LOCAL_encoding, flags, | 
					
						
							| 
									
										
										
										
											2017-06-08 22:16:52 +01:00
										 |  |  |                  AtomRead, NULL); | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  | // like any file stream.
 | 
					
						
							|  |  |  |   /* currently these streams are not seekable */ | 
					
						
							|  |  |  |   st->status = Input_Stream_f | InMemory_Stream_f; | 
					
						
							|  |  |  |   st->u.mem_string.pos = 0; | 
					
						
							|  |  |  |   st->u.mem_string.buf = (char *)buf; | 
					
						
							|  |  |  |   st->u.mem_string.max_size = nchars; | 
					
						
							|  |  |  |   st->u.mem_string.error_handler = NULL; | 
					
						
							|  |  |  | // st->u.mem_string.src = src; check new assets coode
 | 
					
						
							|  |  |  |   Yap_DefaultStreamOps(st); | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-22 18:19:58 +01:00
										 |  |  | int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp, | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |                              memBufSource src) { | 
					
						
							| 
									
										
										
										
											2015-10-08 02:23:45 +01:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |   int sno; | 
					
						
							|  |  |  |   StreamDesc *st; | 
					
						
							| 
									
										
										
										
											2016-01-04 14:11:09 +00:00
										 |  |  |   FILE *f; | 
					
						
							|  |  |  |   encoding_t encoding; | 
					
						
							|  |  |  |   stream_flags_t flags; | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |   sno = GetFreeStreamD(); | 
					
						
							|  |  |  |   if (sno < 0) | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |     return (PlIOError(RESOURCE_ERROR_MAX_STREAMS, TermNil, | 
					
						
							|  |  |  |                       "new stream not available for open_mem_read_stream/1")); | 
					
						
							|  |  |  |   st = GLOBAL_Stream + sno; | 
					
						
							| 
									
										
										
										
											2016-01-04 14:11:09 +00:00
										 |  |  |   if (encp) | 
					
						
							|  |  |  |     encoding = *encp; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     encoding = LOCAL_encoding; | 
					
						
							| 
									
										
										
										
											2016-04-22 18:19:58 +01:00
										 |  |  |   st->file = f = NULL; | 
					
						
							| 
									
										
										
										
											2016-01-04 14:11:09 +00:00
										 |  |  |   flags = Input_Stream_f | InMemory_Stream_f; | 
					
						
							| 
									
										
										
										
											2017-06-05 13:06:12 +01:00
										 |  |  |   st->vfs = NULL; | 
					
						
							| 
									
										
										
										
											2017-06-08 22:16:52 +01:00
										 |  |  |   Yap_initStream(sno, f, NULL, TermNil, encoding, flags, AtomRead, NULL); | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | // like any file stream.
 | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |   /* currently these streams are not seekable */ | 
					
						
							|  |  |  |   st->status = Input_Stream_f | InMemory_Stream_f; | 
					
						
							|  |  |  |   st->u.mem_string.pos = 0; | 
					
						
							| 
									
										
										
										
											2016-04-22 18:19:58 +01:00
										 |  |  |   st->u.mem_string.buf = (char *)buf; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |   st->u.mem_string.max_size = nchars; | 
					
						
							|  |  |  |   st->u.mem_string.error_handler = NULL; | 
					
						
							|  |  |  |   st->u.mem_string.src = src; | 
					
						
							| 
									
										
										
										
											2016-04-08 01:22:27 -07:00
										 |  |  |   Yap_DefaultStreamOps(st); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |   UNLOCK(st->streamlock); | 
					
						
							|  |  |  |   return sno; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  | open_mem_read_stream(USES_REGS1) /* $open_mem_read_stream(+List,-Stream) */ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   Term t, ti; | 
					
						
							|  |  |  |   int sno; | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |   char buf0[YAP_FILENAME_MAX + 1]; | 
					
						
							|  |  |  |   const char *buf; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   ti = Deref(ARG1); | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |   buf = Yap_TextTermToText(ti, buf0, 0, LOCAL_encoding); | 
					
						
							|  |  |  |   if (!buf) { | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |   sno = Yap_open_buf_read_stream(buf, strlen(buf) + 1, &LOCAL_encoding, | 
					
						
							|  |  |  |                                  MEM_BUF_MALLOC); | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   t = Yap_MkStream(sno); | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |   return Yap_unify(ARG2, t); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-22 18:19:58 +01:00
										 |  |  | // open a buffer for writing, currently just ignores buf and nchars.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int Yap_open_buf_write_stream(encoding_t enc, memBufSource src) { | 
					
						
							| 
									
										
										
										
											2015-10-08 02:23:45 +01:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   int sno; | 
					
						
							|  |  |  |   StreamDesc *st; | 
					
						
							| 
									
										
										
										
											2015-08-07 16:57:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   sno = GetFreeStreamD(); | 
					
						
							|  |  |  |   if (sno < 0) | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   st = GLOBAL_Stream + sno; | 
					
						
							| 
									
										
										
										
											2016-09-21 14:43:18 -05:00
										 |  |  |   st->status = Output_Stream_f | InMemory_Stream_f | FreeOnClose_Stream_f; | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   st->linepos = 0; | 
					
						
							|  |  |  |   st->charcount = 0; | 
					
						
							|  |  |  |   st->linecount = 1; | 
					
						
							| 
									
										
										
										
											2016-04-22 18:19:58 +01:00
										 |  |  |   st->encoding = enc; | 
					
						
							| 
									
										
										
										
											2017-06-05 13:06:12 +01:00
										 |  |  |   st->vfs = NULL; | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   Yap_DefaultStreamOps(st); | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |   st->nbuf = st->u.mem_string.buf = malloc(PLGETC_BUF_SIZE); | 
					
						
							| 
									
										
										
										
											2016-09-27 19:32:27 -05:00
										 |  |  |   st->u.mem_string.src = MEM_BUF_MALLOC; | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |   st->u.mem_string.max_size = PLGETC_BUF_SIZE - 1; | 
					
						
							|  |  |  |   st->u.mem_string.pos = 0; | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   UNLOCK(st->streamlock); | 
					
						
							|  |  |  |   return sno; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | int Yap_OpenBufWriteStream(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   return Yap_open_buf_write_stream( | 
					
						
							| 
									
										
										
										
											2016-04-22 18:19:58 +01:00
										 |  |  |       GLOBAL_Stream[LOCAL_c_output_stream].encoding, 0); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  | open_mem_write_stream(USES_REGS1) /* $open_mem_write_stream(-Stream) */ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   Term t; | 
					
						
							|  |  |  |   int sno; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   sno = Yap_OpenBufWriteStream(PASS_REGS1); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |   if (sno == -1) | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |     return (PlIOError(SYSTEM_ERROR_INTERNAL, TermNil, | 
					
						
							|  |  |  |                       "new stream not available for open_mem_read_stream/1")); | 
					
						
							|  |  |  |   t = Yap_MkStream(sno); | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |   GLOBAL_Stream[sno].status |= InMemory_Stream_f; | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   return (Yap_unify(ARG1, t)); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |  * Yap_PeekMemwriteStream() shows the current buffer for a memory stream. | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |  * @param sno, the in-memory stream | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |  * @return temporary buffer, discarded by close and may be moved away | 
					
						
							|  |  |  |  * by other writes.. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | char *Yap_MemExportStreamPtr(int sno) { | 
					
						
							| 
									
										
										
										
											2016-09-27 19:32:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |   GLOBAL_Stream[sno].u.mem_string.buf[GLOBAL_Stream[sno].u.mem_string.pos] = | 
					
						
							|  |  |  |       '\0'; | 
					
						
							| 
									
										
										
										
											2016-01-31 10:02:11 +00:00
										 |  |  |   return GLOBAL_Stream[sno].u.mem_string.buf; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | static Int peek_mem_write_stream( | 
					
						
							|  |  |  |     USES_REGS1) { /* '$peek_mem_write_stream'(+GLOBAL_Stream,?S0,?S) */ | 
					
						
							|  |  |  |   Int sno = | 
					
						
							| 
									
										
										
										
											2016-09-21 14:43:18 -05:00
										 |  |  |       Yap_CheckStream(ARG1, (Output_Stream_f | InMemory_Stream_f), "close/2"); | 
					
						
							| 
									
										
										
										
											2015-07-22 19:33:30 -05:00
										 |  |  |   Int i; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |   Term tf = ARG2; | 
					
						
							|  |  |  |   CELL *HI; | 
					
						
							| 
									
										
										
										
											2015-07-22 19:33:30 -05:00
										 |  |  |   const char *ptr; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (sno < 0) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | restart: | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |   HI = HR; | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   ptr = GLOBAL_Stream[sno].u.mem_string.buf; | 
					
						
							|  |  |  |   i = GLOBAL_Stream[sno].u.mem_string.pos; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |   while (i > 0) { | 
					
						
							|  |  |  |     --i; | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |     tf = MkPairTerm(MkIntTerm(ptr[i]), tf); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |     if (HR + 1024 >= ASP) { | 
					
						
							|  |  |  |       UNLOCK(GLOBAL_Stream[sno].streamlock); | 
					
						
							|  |  |  |       HR = HI; | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |       if (!Yap_gcl((ASP - HI) * sizeof(CELL), 3, ENV, Yap_gcP())) { | 
					
						
							|  |  |  |         UNLOCK(GLOBAL_Stream[sno].streamlock); | 
					
						
							|  |  |  |         Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |         return (FALSE); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |       i = GLOBAL_Stream[sno].u.mem_string.pos; | 
					
						
							|  |  |  |       tf = ARG2; | 
					
						
							|  |  |  |       LOCK(GLOBAL_Stream[sno].streamlock); | 
					
						
							|  |  |  |       goto restart; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   UNLOCK(GLOBAL_Stream[sno].streamlock); | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   return (Yap_unify(ARG3, tf)); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | void Yap_MemOps(StreamDesc *st) { | 
					
						
							|  |  |  |   st->stream_putc = MemPutc; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 19:32:27 -05:00
										 |  |  |   st->stream_getc = MemGetc;} | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | bool Yap_CloseMemoryStream(int sno) { | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |   if ((GLOBAL_Stream[sno].status & Output_Stream_f)) { | 
					
						
							|  |  |  |     if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_MALLOC) { | 
					
						
							| 
									
										
										
										
											2016-01-31 10:02:11 +00:00
										 |  |  |       free(GLOBAL_Stream[sno].u.mem_string.buf); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2016-07-31 09:51:52 -05:00
										 |  |  |     if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_MALLOC) { | 
					
						
							| 
									
										
										
										
											2016-01-31 10:02:11 +00:00
										 |  |  |       free(GLOBAL_Stream[sno].u.mem_string.buf); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2016-01-31 10:02:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 02:53:39 +01:00
										 |  |  | void Yap_InitMems(void) { | 
					
						
							|  |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   Yap_InitCPred("open_mem_read_stream", 2, open_mem_read_stream, SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("open_mem_write_stream", 1, open_mem_write_stream, | 
					
						
							|  |  |  |                 SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("peek_mem_write_stream", 3, peek_mem_write_stream, | 
					
						
							|  |  |  |                 SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:32:33 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-27 19:32:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 09:08:22 -05:00
										 |  |  | #endif
 |