1 /*  $Id$
2 
3     Part of SWI-Prolog
4 
5     Author:        Jan Wielemaker
6     E-mail:        jan@swi.psy.uva.nl
7     WWW:           http://www.swi-prolog.org
8     Copyright (C): 1985-2002, University of Amsterdam
9 
10     This library is free software; you can redistribute it and/or
11     modify it under the terms of the GNU Lesser General Public
12     License as published by the Free Software Foundation; either
13     version 2.1 of the License, or (at your option) any later version.
14 
15     This library is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18     Lesser General Public License for more details.
19 
20     You should have received a copy of the GNU Lesser General Public
21     License along with this library; if not, write to the Free Software
22     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24 
25 #ifndef BUFFER_H_INCLUDED
26 #define BUFFER_H_INCLUDED
27 
28 #define STATIC_BUFFER_SIZE (512)
29 #define BUFFER_USES_MALLOC 1
30 
31 #define BUFFER_RING_SIZE 	16	/* foreign buffer ring (pl-fli.c) */
32 
33 typedef struct
34 { char *	base;			/* allocated base */
35   char *	top;			/* pointer to top */
36   char *	max;			/* current location */
37   char		static_buffer[STATIC_BUFFER_SIZE];
38 } tmp_buffer, *TmpBuffer;
39 
40 typedef struct
41 { char *	base;			/* allocated base */
42   char *	top;			/* pointer to top */
43   char *	max;			/* current location */
44   char		static_buffer[sizeof(char *)];
45 } buffer, *Buffer;
46 
47 void	growBuffer(Buffer b, size_t minfree);
48 
49 Buffer findBuffer(int flags);
50 
51 char *buffer_string(const char *s, int flags);
52 
53 int unfindBuffer(int flags);
54 
55 Buffer codes_or_chars_to_buffer(term_t l, unsigned int flags, int wide);
56 
57 #define addBuffer(b, obj, type) \
58 	do \
59 	{ if ( (b)->top + sizeof(type) > (b)->max ) \
60 	    growBuffer((Buffer)b, sizeof(type)); \
61  	  *((type *)(b)->top) = obj; \
62           (b)->top += sizeof(type); \
63 	} while(0)
64 
65 #define addMultipleBuffer(b, ptr, times, type) \
66 	do \
67 	{ size_t _tms = (times); \
68           size_t _len = _tms * sizeof(type); \
69           type *_d, *_s = (type *)ptr; \
70 	  if ( (b)->top + _len > (b)->max ) \
71 	    growBuffer((Buffer)b, _len); \
72           _d = (type *)(b)->top; \
73           while ( _tms-- ) \
74 	    *_d++ = *_s++; \
75 	  (b)->top = (char *)_d; \
76 	} while(0)
77 
78 #define baseBuffer(b, type)	 ((type *) (b)->base)
79 #define topBuffer(b, type)       ((type *) (b)->top)
80 #define inBuffer(b, addr)        ((char *) (addr) >= (b)->base && \
81 				  (char *) (addr)  < (b)->top)
82 #define fetchBuffer(b, i, type)	 (baseBuffer(b, type)[i])
83 
84 #define seekBuffer(b, cnt, type) ((b)->top = sizeof(type) * (cnt) + (b)->base)
85 #define sizeOfBuffer(b)          ((b)->top - (b)->base)
86 #define freeSpaceBuffer(b)	 ((b)->max - (b)->top)
87 #define entriesBuffer(b, type)   (sizeOfBuffer(b) / sizeof(type))
88 #define initBuffer(b)            ((b)->base = (b)->top = (b)->static_buffer, \
89 				  (b)->max = (b)->base + \
90 				  sizeof((b)->static_buffer))
91 #define emptyBuffer(b)           ((b)->top  = (b)->base)
92 #define isEmptyBuffer(b)         ((b)->top == (b)->base)
93 
94 #ifdef BUFFER_USES_MALLOC
95 #define discardBuffer(b) \
96 	do \
97 	{ if ( (b)->base && (b)->base != (b)->static_buffer ) \
98 	  { free((b)->base); \
99 	    (b)->base = (b)->static_buffer; \
100 	  } \
101 	} while(0)
102 #else
103 #define discardBuffer(b) \
104 	do \
105 	{ if ( (b)->base && (b)->base != (b)->static_buffer ) \
106 	  { freeHeap((b)->base, (b)->max - (b)->base); \
107 	    (b)->base = (b)->static_buffer; \
108 	  } \
109 	} while(0)
110 #endif
111 
112 #endif /*BUFFER_H_INCLUDED*/
113