Commit | Line | Data |
---|---|---|
e6c0deb9 KB |
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. | |
92a1926a | 6 | * |
e6c0deb9 KB |
7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | |
92a1926a | 9 | * |
87198c0c | 10 | * %sccs.include.redist.c% |
92a1926a | 11 | */ |
e6c0deb9 | 12 | |
92a1926a | 13 | #ifndef lint |
fc46faab | 14 | static char sccsid[] = "@(#)buf.c 5.5 (Berkeley) %G%"; |
e6c0deb9 KB |
15 | #endif /* not lint */ |
16 | ||
17 | /*- | |
18 | * buf.c -- | |
19 | * Functions for automatically-expanded buffers. | |
20 | */ | |
92a1926a KB |
21 | |
22 | #include "sprite.h" | |
23 | #include "buf.h" | |
24 | ||
92a1926a KB |
25 | #ifndef max |
26 | #define max(a,b) ((a) > (b) ? (a) : (b)) | |
27 | #endif | |
28 | ||
29 | /* | |
30 | * BufExpand -- | |
31 | * Expand the given buffer to hold the given number of additional | |
32 | * bytes. | |
33 | * Makes sure there's room for an extra NULL byte at the end of the | |
34 | * buffer in case it holds a string. | |
35 | */ | |
36 | #define BufExpand(bp,nb) \ | |
fc46faab | 37 | if (bp->left < (nb)+1) {\ |
92a1926a KB |
38 | int newSize = (bp)->size + max((nb)+1,BUF_ADD_INC); \ |
39 | Byte *newBuf = (Byte *) realloc((bp)->buffer, newSize); \ | |
40 | \ | |
41 | (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \ | |
42 | (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\ | |
43 | (bp)->buffer = newBuf;\ | |
44 | (bp)->size = newSize;\ | |
fc46faab | 45 | (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer);\ |
92a1926a KB |
46 | } |
47 | ||
48 | #define BUF_DEF_SIZE 256 /* Default buffer size */ | |
49 | #define BUF_ADD_INC 256 /* Expansion increment when Adding */ | |
50 | #define BUF_UNGET_INC 16 /* Expansion increment when Ungetting */ | |
51 | ||
52 | /*- | |
53 | *----------------------------------------------------------------------- | |
fc46faab KB |
54 | * Buf_OvAddByte -- |
55 | * Add a single byte to the buffer. left is zero or negative. | |
92a1926a KB |
56 | * |
57 | * Results: | |
58 | * None. | |
59 | * | |
60 | * Side Effects: | |
61 | * The buffer may be expanded. | |
62 | * | |
63 | *----------------------------------------------------------------------- | |
64 | */ | |
65 | void | |
fc46faab KB |
66 | Buf_OvAddByte (bp, byte) |
67 | register Buffer bp; | |
92a1926a KB |
68 | Byte byte; |
69 | { | |
92a1926a | 70 | |
fc46faab | 71 | bp->left = 0; |
92a1926a KB |
72 | BufExpand (bp, 1); |
73 | ||
fc46faab KB |
74 | *bp->inPtr++ = byte; |
75 | bp->left--; | |
92a1926a KB |
76 | |
77 | /* | |
78 | * Null-terminate | |
79 | */ | |
80 | *bp->inPtr = 0; | |
81 | } | |
82 | \f | |
83 | /*- | |
84 | *----------------------------------------------------------------------- | |
85 | * Buf_AddBytes -- | |
86 | * Add a number of bytes to the buffer. | |
87 | * | |
88 | * Results: | |
89 | * None. | |
90 | * | |
91 | * Side Effects: | |
92 | * Guess what? | |
93 | * | |
94 | *----------------------------------------------------------------------- | |
95 | */ | |
96 | void | |
fc46faab KB |
97 | Buf_AddBytes (bp, numBytes, bytesPtr) |
98 | register Buffer bp; | |
92a1926a KB |
99 | int numBytes; |
100 | Byte *bytesPtr; | |
101 | { | |
92a1926a KB |
102 | |
103 | BufExpand (bp, numBytes); | |
104 | ||
105 | bcopy (bytesPtr, bp->inPtr, numBytes); | |
106 | bp->inPtr += numBytes; | |
fc46faab | 107 | bp->left -= numBytes; |
92a1926a KB |
108 | |
109 | /* | |
110 | * Null-terminate | |
111 | */ | |
112 | *bp->inPtr = 0; | |
113 | } | |
114 | \f | |
115 | /*- | |
116 | *----------------------------------------------------------------------- | |
117 | * Buf_UngetByte -- | |
118 | * Place the byte back at the beginning of the buffer. | |
119 | * | |
120 | * Results: | |
121 | * SUCCESS if the byte was added ok. FAILURE if not. | |
122 | * | |
123 | * Side Effects: | |
124 | * The byte is stuffed in the buffer and outPtr is decremented. | |
125 | * | |
126 | *----------------------------------------------------------------------- | |
127 | */ | |
128 | void | |
fc46faab KB |
129 | Buf_UngetByte (bp, byte) |
130 | register Buffer bp; | |
92a1926a KB |
131 | Byte byte; |
132 | { | |
92a1926a KB |
133 | |
134 | if (bp->outPtr != bp->buffer) { | |
fc46faab | 135 | bp->outPtr--; |
92a1926a KB |
136 | *bp->outPtr = byte; |
137 | } else if (bp->outPtr == bp->inPtr) { | |
138 | *bp->inPtr = byte; | |
fc46faab KB |
139 | bp->inPtr++; |
140 | bp->left--; | |
92a1926a KB |
141 | *bp->inPtr = 0; |
142 | } else { | |
143 | /* | |
144 | * Yech. have to expand the buffer to stuff this thing in. | |
145 | * We use a different expansion constant because people don't | |
146 | * usually push back many bytes when they're doing it a byte at | |
147 | * a time... | |
148 | */ | |
149 | int numBytes = bp->inPtr - bp->outPtr; | |
150 | Byte *newBuf; | |
151 | ||
644c011b | 152 | newBuf = (Byte *)emalloc(bp->size + BUF_UNGET_INC); |
fc46faab KB |
153 | bcopy ((char *)bp->outPtr, |
154 | (char *)(newBuf+BUF_UNGET_INC), numBytes+1); | |
92a1926a KB |
155 | bp->outPtr = newBuf + BUF_UNGET_INC; |
156 | bp->inPtr = bp->outPtr + numBytes; | |
fc46faab | 157 | free ((char *)bp->buffer); |
92a1926a KB |
158 | bp->buffer = newBuf; |
159 | bp->size += BUF_UNGET_INC; | |
fc46faab | 160 | bp->left = bp->size - (bp->inPtr - bp->buffer); |
92a1926a KB |
161 | bp->outPtr -= 1; |
162 | *bp->outPtr = byte; | |
163 | } | |
164 | } | |
165 | \f | |
166 | /*- | |
167 | *----------------------------------------------------------------------- | |
168 | * Buf_UngetBytes -- | |
169 | * Push back a series of bytes at the beginning of the buffer. | |
170 | * | |
171 | * Results: | |
172 | * None. | |
173 | * | |
174 | * Side Effects: | |
175 | * outPtr is decremented and the bytes copied into the buffer. | |
176 | * | |
177 | *----------------------------------------------------------------------- | |
178 | */ | |
179 | void | |
fc46faab KB |
180 | Buf_UngetBytes (bp, numBytes, bytesPtr) |
181 | register Buffer bp; | |
92a1926a KB |
182 | int numBytes; |
183 | Byte *bytesPtr; | |
184 | { | |
92a1926a KB |
185 | |
186 | if (bp->outPtr - bp->buffer >= numBytes) { | |
187 | bp->outPtr -= numBytes; | |
188 | bcopy (bytesPtr, bp->outPtr, numBytes); | |
189 | } else if (bp->outPtr == bp->inPtr) { | |
fc46faab | 190 | Buf_AddBytes (bp, numBytes, bytesPtr); |
92a1926a KB |
191 | } else { |
192 | int curNumBytes = bp->inPtr - bp->outPtr; | |
193 | Byte *newBuf; | |
194 | int newBytes = max(numBytes,BUF_UNGET_INC); | |
195 | ||
644c011b | 196 | newBuf = (Byte *)emalloc (bp->size + newBytes); |
fc46faab | 197 | bcopy((char *)bp->outPtr, (char *)(newBuf+newBytes), curNumBytes+1); |
92a1926a KB |
198 | bp->outPtr = newBuf + newBytes; |
199 | bp->inPtr = bp->outPtr + curNumBytes; | |
fc46faab | 200 | free ((char *)bp->buffer); |
92a1926a KB |
201 | bp->buffer = newBuf; |
202 | bp->size += newBytes; | |
fc46faab | 203 | bp->left = bp->size - (bp->inPtr - bp->buffer); |
92a1926a | 204 | bp->outPtr -= numBytes; |
fc46faab | 205 | bcopy ((char *)bytesPtr, (char *)bp->outPtr, numBytes); |
92a1926a KB |
206 | } |
207 | } | |
208 | \f | |
209 | /*- | |
210 | *----------------------------------------------------------------------- | |
211 | * Buf_GetByte -- | |
212 | * Return the next byte from the buffer. Actually returns an integer. | |
213 | * | |
214 | * Results: | |
215 | * Returns BUF_ERROR if there's no byte in the buffer, or the byte | |
216 | * itself if there is one. | |
217 | * | |
218 | * Side Effects: | |
219 | * outPtr is incremented and both outPtr and inPtr will be reset if | |
220 | * the buffer is emptied. | |
221 | * | |
222 | *----------------------------------------------------------------------- | |
223 | */ | |
224 | int | |
fc46faab KB |
225 | Buf_GetByte (bp) |
226 | register Buffer bp; | |
92a1926a | 227 | { |
92a1926a KB |
228 | int res; |
229 | ||
230 | if (bp->inPtr == bp->outPtr) { | |
231 | return (BUF_ERROR); | |
232 | } else { | |
233 | res = (int) *bp->outPtr; | |
234 | bp->outPtr += 1; | |
235 | if (bp->outPtr == bp->inPtr) { | |
236 | bp->outPtr = bp->inPtr = bp->buffer; | |
fc46faab KB |
237 | bp->left = bp->size; |
238 | *bp->inPtr = 0; | |
92a1926a KB |
239 | } |
240 | return (res); | |
241 | } | |
242 | } | |
243 | \f | |
244 | /*- | |
245 | *----------------------------------------------------------------------- | |
246 | * Buf_GetBytes -- | |
247 | * Extract a number of bytes from the buffer. | |
248 | * | |
249 | * Results: | |
250 | * The number of bytes gotten. | |
251 | * | |
252 | * Side Effects: | |
253 | * The passed array is overwritten. | |
254 | * | |
255 | *----------------------------------------------------------------------- | |
256 | */ | |
257 | int | |
fc46faab KB |
258 | Buf_GetBytes (bp, numBytes, bytesPtr) |
259 | register Buffer bp; | |
92a1926a KB |
260 | int numBytes; |
261 | Byte *bytesPtr; | |
262 | { | |
92a1926a KB |
263 | |
264 | if (bp->inPtr - bp->outPtr < numBytes) { | |
265 | numBytes = bp->inPtr - bp->outPtr; | |
266 | } | |
267 | bcopy (bp->outPtr, bytesPtr, numBytes); | |
268 | bp->outPtr += numBytes; | |
269 | ||
270 | if (bp->outPtr == bp->inPtr) { | |
271 | bp->outPtr = bp->inPtr = bp->buffer; | |
fc46faab | 272 | bp->left = bp->size; |
92a1926a KB |
273 | *bp->inPtr = 0; |
274 | } | |
275 | return (numBytes); | |
276 | } | |
277 | \f | |
278 | /*- | |
279 | *----------------------------------------------------------------------- | |
280 | * Buf_GetAll -- | |
281 | * Get all the available data at once. | |
282 | * | |
283 | * Results: | |
284 | * A pointer to the data and the number of bytes available. | |
285 | * | |
286 | * Side Effects: | |
287 | * None. | |
288 | * | |
289 | *----------------------------------------------------------------------- | |
290 | */ | |
291 | Byte * | |
fc46faab KB |
292 | Buf_GetAll (bp, numBytesPtr) |
293 | register Buffer bp; | |
92a1926a KB |
294 | int *numBytesPtr; |
295 | { | |
92a1926a KB |
296 | |
297 | if (numBytesPtr != (int *)NULL) { | |
298 | *numBytesPtr = bp->inPtr - bp->outPtr; | |
299 | } | |
300 | ||
301 | return (bp->outPtr); | |
302 | } | |
303 | \f | |
304 | /*- | |
305 | *----------------------------------------------------------------------- | |
306 | * Buf_Discard -- | |
307 | * Throw away bytes in a buffer. | |
308 | * | |
309 | * Results: | |
310 | * None. | |
311 | * | |
312 | * Side Effects: | |
313 | * The bytes are discarded. | |
314 | * | |
315 | *----------------------------------------------------------------------- | |
316 | */ | |
317 | void | |
fc46faab KB |
318 | Buf_Discard (bp, numBytes) |
319 | register Buffer bp; | |
92a1926a KB |
320 | int numBytes; |
321 | { | |
92a1926a KB |
322 | |
323 | if (bp->inPtr - bp->outPtr <= numBytes) { | |
324 | bp->inPtr = bp->outPtr = bp->buffer; | |
fc46faab | 325 | bp->left = bp->size; |
92a1926a KB |
326 | *bp->inPtr = 0; |
327 | } else { | |
328 | bp->outPtr += numBytes; | |
329 | } | |
330 | } | |
331 | \f | |
332 | /*- | |
333 | *----------------------------------------------------------------------- | |
334 | * Buf_Size -- | |
335 | * Returns the number of bytes in the given buffer. Doesn't include | |
336 | * the null-terminating byte. | |
337 | * | |
338 | * Results: | |
339 | * The number of bytes. | |
340 | * | |
341 | * Side Effects: | |
342 | * None. | |
343 | * | |
344 | *----------------------------------------------------------------------- | |
345 | */ | |
346 | int | |
347 | Buf_Size (buf) | |
348 | Buffer buf; | |
349 | { | |
fc46faab | 350 | return (buf->inPtr - buf->outPtr); |
92a1926a KB |
351 | } |
352 | \f | |
353 | /*- | |
354 | *----------------------------------------------------------------------- | |
355 | * Buf_Init -- | |
356 | * Initialize a buffer. If no initial size is given, a reasonable | |
357 | * default is used. | |
358 | * | |
359 | * Results: | |
360 | * A buffer to be given to other functions in this library. | |
361 | * | |
362 | * Side Effects: | |
363 | * The buffer is created, the space allocated and pointers | |
364 | * initialized. | |
365 | * | |
366 | *----------------------------------------------------------------------- | |
367 | */ | |
368 | Buffer | |
369 | Buf_Init (size) | |
370 | int size; /* Initial size for the buffer */ | |
371 | { | |
fc46faab | 372 | Buffer bp; /* New Buffer */ |
92a1926a | 373 | |
fc46faab | 374 | bp = (Buffer)emalloc(sizeof(*bp)); |
92a1926a KB |
375 | |
376 | if (size <= 0) { | |
377 | size = BUF_DEF_SIZE; | |
378 | } | |
fc46faab KB |
379 | bp->left = bp->size = size; |
380 | bp->buffer = (Byte *)emalloc(size); | |
92a1926a KB |
381 | bp->inPtr = bp->outPtr = bp->buffer; |
382 | *bp->inPtr = 0; | |
383 | ||
fc46faab | 384 | return (bp); |
92a1926a KB |
385 | } |
386 | \f | |
387 | /*- | |
388 | *----------------------------------------------------------------------- | |
389 | * Buf_Destroy -- | |
390 | * Nuke a buffer and all its resources. | |
391 | * | |
392 | * Results: | |
393 | * None. | |
394 | * | |
395 | * Side Effects: | |
396 | * The buffer is freed. | |
397 | * | |
398 | *----------------------------------------------------------------------- | |
399 | */ | |
400 | void | |
401 | Buf_Destroy (buf, freeData) | |
402 | Buffer buf; /* Buffer to destroy */ | |
403 | Boolean freeData; /* TRUE if the data should be destroyed as well */ | |
404 | { | |
92a1926a KB |
405 | |
406 | if (freeData) { | |
fc46faab | 407 | free ((char *)buf->buffer); |
92a1926a | 408 | } |
fc46faab | 409 | free ((char *)buf); |
92a1926a | 410 | } |