VirtualBox

source: kBuild/trunk/src/kmk/buf.c@ 93

Last change on this file since 93 was 51, checked in by bird, 22 years ago

kMk and porting to kLib.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
Line 
1/*
2 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
3 * Copyright (c) 1988, 1989 by Adam de Boor
4 * Copyright (c) 1989 by Berkeley Softworks
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39#ifndef lint
40#if 0
41static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93";
42#else
43static const char rcsid[] =
44 "$FreeBSD: src/usr.bin/make/buf.c,v 1.11 1999/09/11 13:08:01 hoek Exp $";
45#endif
46#define KLIBFILEDEF rcsid
47#endif /* not lint */
48
49/*-
50 * buf.c --
51 * Functions for automatically-expanded buffers.
52 */
53
54#include "sprite.h"
55#include "make.h"
56#include "buf.h"
57
58#ifndef max
59#define max(a,b) ((a) > (b) ? (a) : (b))
60#endif
61
62/*
63 * BufExpand --
64 * Expand the given buffer to hold the given number of additional
65 * bytes.
66 * Makes sure there's room for an extra NULL byte at the end of the
67 * buffer in case it holds a string.
68 */
69#define BufExpand(bp,nb) \
70 if (bp->left < (nb)+1) {\
71 int newSize = (bp)->size + max((nb)+1,BUF_ADD_INC); \
72 Byte *newBuf = (Byte *) erealloc((bp)->buffer, newSize); \
73 \
74 (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \
75 (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\
76 (bp)->buffer = newBuf;\
77 (bp)->size = newSize;\
78 (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer);\
79 }
80
81#define BUF_DEF_SIZE 256 /* Default buffer size */
82#define BUF_ADD_INC 256 /* Expansion increment when Adding */
83#define BUF_UNGET_INC 16 /* Expansion increment when Ungetting */
84
85/*-
86 *-----------------------------------------------------------------------
87 * Buf_OvAddByte --
88 * Add a single byte to the buffer. left is zero or negative.
89 *
90 * Results:
91 * None.
92 *
93 * Side Effects:
94 * The buffer may be expanded.
95 *
96 *-----------------------------------------------------------------------
97 */
98void
99Buf_OvAddByte (bp, byte)
100 register Buffer bp;
101 int byte;
102{
103 int nbytes = 1;
104 bp->left = 0;
105 BufExpand (bp, nbytes);
106
107 *bp->inPtr++ = byte;
108 bp->left--;
109
110 /*
111 * Null-terminate
112 */
113 *bp->inPtr = 0;
114}
115
116
117/*-
118 *-----------------------------------------------------------------------
119 * Buf_AddBytes --
120 * Add a number of bytes to the buffer.
121 *
122 * Results:
123 * None.
124 *
125 * Side Effects:
126 * Guess what?
127 *
128 *-----------------------------------------------------------------------
129 */
130void
131Buf_AddBytes (bp, numBytes, bytesPtr)
132 register Buffer bp;
133 int numBytes;
134 const Byte *bytesPtr;
135{
136
137 BufExpand (bp, numBytes);
138
139 memcpy (bp->inPtr, bytesPtr, numBytes);
140 bp->inPtr += numBytes;
141 bp->left -= numBytes;
142
143 /*
144 * Null-terminate
145 */
146 *bp->inPtr = 0;
147}
148
149
150/*-
151 *-----------------------------------------------------------------------
152 * Buf_UngetByte --
153 * Place the byte back at the beginning of the buffer.
154 *
155 * Results:
156 * SUCCESS if the byte was added ok. FAILURE if not.
157 *
158 * Side Effects:
159 * The byte is stuffed in the buffer and outPtr is decremented.
160 *
161 *-----------------------------------------------------------------------
162 */
163void
164Buf_UngetByte (bp, byte)
165 register Buffer bp;
166 int byte;
167{
168
169 if (bp->outPtr != bp->buffer) {
170 bp->outPtr--;
171 *bp->outPtr = byte;
172 } else if (bp->outPtr == bp->inPtr) {
173 *bp->inPtr = byte;
174 bp->inPtr++;
175 bp->left--;
176 *bp->inPtr = 0;
177 } else {
178 /*
179 * Yech. have to expand the buffer to stuff this thing in.
180 * We use a different expansion constant because people don't
181 * usually push back many bytes when they're doing it a byte at
182 * a time...
183 */
184 int numBytes = bp->inPtr - bp->outPtr;
185 Byte *newBuf;
186
187 newBuf = (Byte *)emalloc(bp->size + BUF_UNGET_INC);
188 memcpy ((char *)(newBuf+BUF_UNGET_INC), (char *)bp->outPtr, numBytes+1);
189 bp->outPtr = newBuf + BUF_UNGET_INC;
190 bp->inPtr = bp->outPtr + numBytes;
191 efree ((char *)bp->buffer);
192 bp->buffer = newBuf;
193 bp->size += BUF_UNGET_INC;
194 bp->left = bp->size - (bp->inPtr - bp->buffer);
195 bp->outPtr -= 1;
196 *bp->outPtr = byte;
197 }
198}
199
200
201/*-
202 *-----------------------------------------------------------------------
203 * Buf_UngetBytes --
204 * Push back a series of bytes at the beginning of the buffer.
205 *
206 * Results:
207 * None.
208 *
209 * Side Effects:
210 * outPtr is decremented and the bytes copied into the buffer.
211 *
212 *-----------------------------------------------------------------------
213 */
214void
215Buf_UngetBytes (bp, numBytes, bytesPtr)
216 register Buffer bp;
217 int numBytes;
218 Byte *bytesPtr;
219{
220
221 if (bp->outPtr - bp->buffer >= numBytes) {
222 bp->outPtr -= numBytes;
223 memcpy (bp->outPtr, bytesPtr, numBytes);
224 } else if (bp->outPtr == bp->inPtr) {
225 Buf_AddBytes (bp, numBytes, bytesPtr);
226 } else {
227 int curNumBytes = bp->inPtr - bp->outPtr;
228 Byte *newBuf;
229 int newBytes = max(numBytes,BUF_UNGET_INC);
230
231 newBuf = (Byte *)emalloc (bp->size + newBytes);
232 memcpy((char *)(newBuf+newBytes), (char *)bp->outPtr, curNumBytes+1);
233 bp->outPtr = newBuf + newBytes;
234 bp->inPtr = bp->outPtr + curNumBytes;
235 efree ((char *)bp->buffer);
236 bp->buffer = newBuf;
237 bp->size += newBytes;
238 bp->left = bp->size - (bp->inPtr - bp->buffer);
239 bp->outPtr -= numBytes;
240 memcpy ((char *)bp->outPtr, (char *)bytesPtr, numBytes);
241 }
242}
243
244
245/*-
246 *-----------------------------------------------------------------------
247 * Buf_GetByte --
248 * Return the next byte from the buffer. Actually returns an integer.
249 *
250 * Results:
251 * Returns BUF_ERROR if there's no byte in the buffer, or the byte
252 * itself if there is one.
253 *
254 * Side Effects:
255 * outPtr is incremented and both outPtr and inPtr will be reset if
256 * the buffer is emptied.
257 *
258 *-----------------------------------------------------------------------
259 */
260int
261Buf_GetByte (bp)
262 register Buffer bp;
263{
264 int res;
265
266 if (bp->inPtr == bp->outPtr) {
267 return (BUF_ERROR);
268 } else {
269 res = (int) *bp->outPtr;
270 bp->outPtr += 1;
271 if (bp->outPtr == bp->inPtr) {
272 bp->outPtr = bp->inPtr = bp->buffer;
273 bp->left = bp->size;
274 *bp->inPtr = 0;
275 }
276 return (res);
277 }
278}
279
280
281/*-
282 *-----------------------------------------------------------------------
283 * Buf_GetBytes --
284 * Extract a number of bytes from the buffer.
285 *
286 * Results:
287 * The number of bytes gotten.
288 *
289 * Side Effects:
290 * The passed array is overwritten.
291 *
292 *-----------------------------------------------------------------------
293 */
294int
295Buf_GetBytes (bp, numBytes, bytesPtr)
296 register Buffer bp;
297 int numBytes;
298 Byte *bytesPtr;
299{
300
301 if (bp->inPtr - bp->outPtr < numBytes) {
302 numBytes = bp->inPtr - bp->outPtr;
303 }
304 memcpy (bytesPtr, bp->outPtr, numBytes);
305 bp->outPtr += numBytes;
306
307 if (bp->outPtr == bp->inPtr) {
308 bp->outPtr = bp->inPtr = bp->buffer;
309 bp->left = bp->size;
310 *bp->inPtr = 0;
311 }
312 return (numBytes);
313}
314
315
316/*-
317 *-----------------------------------------------------------------------
318 * Buf_GetAll --
319 * Get all the available data at once.
320 *
321 * Results:
322 * A pointer to the data and the number of bytes available.
323 *
324 * Side Effects:
325 * None.
326 *
327 *-----------------------------------------------------------------------
328 */
329Byte *
330Buf_GetAll (bp, numBytesPtr)
331 register Buffer bp;
332 int *numBytesPtr;
333{
334
335 if (numBytesPtr != (int *)NULL) {
336 *numBytesPtr = bp->inPtr - bp->outPtr;
337 }
338
339 return (bp->outPtr);
340}
341
342
343/*-
344 *-----------------------------------------------------------------------
345 * Buf_Discard --
346 * Throw away bytes in a buffer.
347 *
348 * Results:
349 * None.
350 *
351 * Side Effects:
352 * The bytes are discarded.
353 *
354 *-----------------------------------------------------------------------
355 */
356void
357Buf_Discard (bp, numBytes)
358 register Buffer bp;
359 int numBytes;
360{
361
362 if (bp->inPtr - bp->outPtr <= numBytes) {
363 bp->inPtr = bp->outPtr = bp->buffer;
364 bp->left = bp->size;
365 *bp->inPtr = 0;
366 } else {
367 bp->outPtr += numBytes;
368 }
369}
370
371
372/*-
373 *-----------------------------------------------------------------------
374 * Buf_Size --
375 * Returns the number of bytes in the given buffer. Doesn't include
376 * the null-terminating byte.
377 *
378 * Results:
379 * The number of bytes.
380 *
381 * Side Effects:
382 * None.
383 *
384 *-----------------------------------------------------------------------
385 */
386int
387Buf_Size (buf)
388 Buffer buf;
389{
390 return (buf->inPtr - buf->outPtr);
391}
392
393
394/*-
395 *-----------------------------------------------------------------------
396 * Buf_Init --
397 * Initialize a buffer. If no initial size is given, a reasonable
398 * default is used.
399 *
400 * Results:
401 * A buffer to be given to other functions in this library.
402 *
403 * Side Effects:
404 * The buffer is created, the space allocated and pointers
405 * initialized.
406 *
407 *-----------------------------------------------------------------------
408 */
409Buffer
410Buf_Init (size)
411 int size; /* Initial size for the buffer */
412{
413 Buffer bp; /* New Buffer */
414
415 bp = (Buffer)emalloc(sizeof(*bp));
416
417 if (size <= 0) {
418 size = BUF_DEF_SIZE;
419 }
420 bp->left = bp->size = size;
421 bp->buffer = (Byte *)emalloc(size);
422 bp->inPtr = bp->outPtr = bp->buffer;
423 *bp->inPtr = 0;
424
425 return (bp);
426}
427
428
429/*-
430 *-----------------------------------------------------------------------
431 * Buf_Destroy --
432 * Nuke a buffer and all its resources.
433 *
434 * Results:
435 * None.
436 *
437 * Side Effects:
438 * The buffer is freed.
439 *
440 *-----------------------------------------------------------------------
441 */
442void
443Buf_Destroy (buf, freeData)
444 Buffer buf; /* Buffer to destroy */
445 Boolean freeData; /* TRUE if the data should be destroyed as well */
446{
447
448 if (freeData) {
449 efree ((char *)buf->buffer);
450 }
451 efree ((char *)buf);
452}
453
454
455/*-
456 *-----------------------------------------------------------------------
457 * Buf_ReplaceLastByte --
458 * Replace the last byte in a buffer.
459 *
460 * Results:
461 * None.
462 *
463 * Side Effects:
464 * If the buffer was empty intially, then a new byte will be added.
465 * Otherwise, the last byte is overwritten.
466 *
467 *-----------------------------------------------------------------------
468 */
469void
470Buf_ReplaceLastByte (buf, byte)
471 Buffer buf; /* buffer to augment */
472 int byte; /* byte to be written */
473{
474 if (buf->inPtr == buf->outPtr)
475 Buf_AddByte(buf, byte);
476 else
477 *(buf->inPtr - 1) = byte;
478}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette