buf.c revision 1.12 1 /* $NetBSD: buf.c,v 1.12 1999/09/15 04:16:31 mycroft Exp $ */
2
3 /*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * Copyright (c) 1988, 1989 by Adam de Boor
6 * Copyright (c) 1989 by Berkeley Softworks
7 * All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
10 * Adam de Boor.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 */
40
41 #ifdef MAKE_BOOTSTRAP
42 static char rcsid[] = "$NetBSD: buf.c,v 1.12 1999/09/15 04:16:31 mycroft Exp $";
43 #else
44 #include <sys/cdefs.h>
45 #ifndef lint
46 #if 0
47 static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93";
48 #else
49 __RCSID("$NetBSD: buf.c,v 1.12 1999/09/15 04:16:31 mycroft Exp $");
50 #endif
51 #endif /* not lint */
52 #endif
53
54 /*-
55 * buf.c --
56 * Functions for automatically-expanded buffers.
57 */
58
59 #include "sprite.h"
60 #include "make.h"
61 #include "buf.h"
62
63 #ifndef max
64 #define max(a,b) ((a) > (b) ? (a) : (b))
65 #endif
66
67 /*
68 * BufExpand --
69 * Expand the given buffer to hold the given number of additional
70 * bytes.
71 * Makes sure there's room for an extra NULL byte at the end of the
72 * buffer in case it holds a string.
73 */
74 #define BufExpand(bp,nb) \
75 while (bp->left < (nb)+1) {\
76 int newSize = (bp)->size * 2; \
77 Byte *newBuf = (Byte *) erealloc((bp)->buffer, newSize); \
78 \
79 (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \
80 (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\
81 (bp)->buffer = newBuf;\
82 (bp)->size = newSize;\
83 (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer);\
84 }
85
86 #define BUF_DEF_SIZE 256 /* Default buffer size */
87
88 /*-
89 *-----------------------------------------------------------------------
90 * Buf_OvAddByte --
91 * Add a single byte to the buffer. left is zero or negative.
92 *
93 * Results:
94 * None.
95 *
96 * Side Effects:
97 * The buffer may be expanded.
98 *
99 *-----------------------------------------------------------------------
100 */
101 void
102 Buf_OvAddByte (bp, byte)
103 register Buffer bp;
104 int byte;
105 {
106 int nbytes = 1;
107 bp->left = 0;
108 BufExpand (bp, nbytes);
109
110 *bp->inPtr++ = byte;
111 bp->left--;
112
113 /*
114 * Null-terminate
115 */
116 *bp->inPtr = 0;
117 }
118
119 /*-
121 *-----------------------------------------------------------------------
122 * Buf_AddBytes --
123 * Add a number of bytes to the buffer.
124 *
125 * Results:
126 * None.
127 *
128 * Side Effects:
129 * Guess what?
130 *
131 *-----------------------------------------------------------------------
132 */
133 void
134 Buf_AddBytes (bp, numBytes, bytesPtr)
135 register Buffer bp;
136 int numBytes;
137 const Byte *bytesPtr;
138 {
139
140 BufExpand (bp, numBytes);
141
142 memcpy (bp->inPtr, bytesPtr, numBytes);
143 bp->inPtr += numBytes;
144 bp->left -= numBytes;
145
146 /*
147 * Null-terminate
148 */
149 *bp->inPtr = 0;
150 }
151
152 /*-
154 *-----------------------------------------------------------------------
155 * Buf_GetAll --
156 * Get all the available data at once.
157 *
158 * Results:
159 * A pointer to the data and the number of bytes available.
160 *
161 * Side Effects:
162 * None.
163 *
164 *-----------------------------------------------------------------------
165 */
166 Byte *
167 Buf_GetAll (bp, numBytesPtr)
168 register Buffer bp;
169 int *numBytesPtr;
170 {
171
172 if (numBytesPtr != (int *)NULL) {
173 *numBytesPtr = bp->inPtr - bp->outPtr;
174 }
175
176 return (bp->outPtr);
177 }
178
179 /*-
181 *-----------------------------------------------------------------------
182 * Buf_Discard --
183 * Throw away bytes in a buffer.
184 *
185 * Results:
186 * None.
187 *
188 * Side Effects:
189 * The bytes are discarded.
190 *
191 *-----------------------------------------------------------------------
192 */
193 void
194 Buf_Discard (bp, numBytes)
195 register Buffer bp;
196 int numBytes;
197 {
198
199 if (bp->inPtr - bp->outPtr <= numBytes) {
200 bp->inPtr = bp->outPtr = bp->buffer;
201 bp->left = bp->size;
202 *bp->inPtr = 0;
203 } else {
204 bp->outPtr += numBytes;
205 }
206 }
207
208 /*-
210 *-----------------------------------------------------------------------
211 * Buf_Size --
212 * Returns the number of bytes in the given buffer. Doesn't include
213 * the null-terminating byte.
214 *
215 * Results:
216 * The number of bytes.
217 *
218 * Side Effects:
219 * None.
220 *
221 *-----------------------------------------------------------------------
222 */
223 int
224 Buf_Size (buf)
225 Buffer buf;
226 {
227 return (buf->inPtr - buf->outPtr);
228 }
229
230 /*-
232 *-----------------------------------------------------------------------
233 * Buf_Init --
234 * Initialize a buffer. If no initial size is given, a reasonable
235 * default is used.
236 *
237 * Results:
238 * A buffer to be given to other functions in this library.
239 *
240 * Side Effects:
241 * The buffer is created, the space allocated and pointers
242 * initialized.
243 *
244 *-----------------------------------------------------------------------
245 */
246 Buffer
247 Buf_Init (size)
248 int size; /* Initial size for the buffer */
249 {
250 Buffer bp; /* New Buffer */
251
252 bp = (Buffer)emalloc(sizeof(*bp));
253
254 if (size <= 0) {
255 size = BUF_DEF_SIZE;
256 }
257 bp->left = bp->size = size;
258 bp->buffer = (Byte *)emalloc(size);
259 bp->inPtr = bp->outPtr = bp->buffer;
260 *bp->inPtr = 0;
261
262 return (bp);
263 }
264
265 /*-
267 *-----------------------------------------------------------------------
268 * Buf_Destroy --
269 * Nuke a buffer and all its resources.
270 *
271 * Results:
272 * None.
273 *
274 * Side Effects:
275 * The buffer is freed.
276 *
277 *-----------------------------------------------------------------------
278 */
279 void
280 Buf_Destroy (buf, freeData)
281 Buffer buf; /* Buffer to destroy */
282 Boolean freeData; /* TRUE if the data should be destroyed as well */
283 {
284
285 if (freeData) {
286 free ((char *)buf->buffer);
287 }
288 free ((char *)buf);
289 }
290
291 /*-
293 *-----------------------------------------------------------------------
294 * Buf_ReplaceLastByte --
295 * Replace the last byte in a buffer.
296 *
297 * Results:
298 * None.
299 *
300 * Side Effects:
301 * If the buffer was empty intially, then a new byte will be added.
302 * Otherwise, the last byte is overwritten.
303 *
304 *-----------------------------------------------------------------------
305 */
306 void
307 Buf_ReplaceLastByte (buf, byte)
308 Buffer buf; /* buffer to augment */
309 int byte; /* byte to be written */
310 {
311 if (buf->inPtr == buf->outPtr)
312 Buf_AddByte(buf, byte);
313 else
314 *(buf->inPtr - 1) = byte;
315 }
316