|
|
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.