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