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