1 /* $NetBSD: buf.c,v 1.12 1999/09/15 04:16:31 mycroft Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 5 * Copyright (c) 1988, 1989 by Adam de Boor 6 * Copyright (c) 1989 by Berkeley Softworks 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * Adam de Boor. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 */ 40 41 #ifdef MAKE_BOOTSTRAP 42 static char rcsid[] = "$NetBSD: buf.c,v 1.12 1999/09/15 04:16:31 mycroft Exp $"; 43 #else 44 #include <sys/cdefs.h> 45 #ifndef lint 46 #if 0 47 static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93"; 48 #else 49 __RCSID("$NetBSD: buf.c,v 1.12 1999/09/15 04:16:31 mycroft Exp $"); 50 #endif 51 #endif /* not lint */ 52 #endif 53 54 /*- 55 * buf.c -- 56 * Functions for automatically-expanded buffers. 57 */ 58 59 #include "sprite.h" 60 #include "make.h" 61 #include "buf.h" 62 63 #ifndef max 64 #define max(a,b) ((a) > (b) ? (a) : (b)) 65 #endif 66 67 /* 68 * BufExpand -- 69 * Expand the given buffer to hold the given number of additional 70 * bytes. 71 * Makes sure there's room for an extra NULL byte at the end of the 72 * buffer in case it holds a string. 73 */ 74 #define BufExpand(bp,nb) \ 75 while (bp->left < (nb)+1) {\ 76 int newSize = (bp)->size * 2; \ 77 Byte *newBuf = (Byte *) erealloc((bp)->buffer, newSize); \ 78 \ 79 (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \ 80 (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\ 81 (bp)->buffer = newBuf;\ 82 (bp)->size = newSize;\ 83 (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer);\ 84 } 85 86 #define BUF_DEF_SIZE 256 /* Default buffer size */ 87 88 /*- 89 *----------------------------------------------------------------------- 90 * Buf_OvAddByte -- 91 * Add a single byte to the buffer. left is zero or negative. 92 * 93 * Results: 94 * None. 95 * 96 * Side Effects: 97 * The buffer may be expanded. 98 * 99 *----------------------------------------------------------------------- 100 */ 101 void 102 Buf_OvAddByte (bp, byte) 103 register Buffer bp; 104 int byte; 105 { 106 int nbytes = 1; 107 bp->left = 0; 108 BufExpand (bp, nbytes); 109 110 *bp->inPtr++ = byte; 111 bp->left--; 112 113 /* 114 * Null-terminate 115 */ 116 *bp->inPtr = 0; 117 } 118 119 /*- 120 *----------------------------------------------------------------------- 121 * Buf_AddBytes -- 122 * Add a number of bytes to the buffer. 123 * 124 * Results: 125 * None. 126 * 127 * Side Effects: 128 * Guess what? 129 * 130 *----------------------------------------------------------------------- 131 */ 132 void 133 Buf_AddBytes (bp, numBytes, bytesPtr) 134 register Buffer bp; 135 int numBytes; 136 const Byte *bytesPtr; 137 { 138 139 BufExpand (bp, numBytes); 140 141 memcpy (bp->inPtr, bytesPtr, numBytes); 142 bp->inPtr += numBytes; 143 bp->left -= numBytes; 144 145 /* 146 * Null-terminate 147 */ 148 *bp->inPtr = 0; 149 } 150 151 /*- 152 *----------------------------------------------------------------------- 153 * Buf_GetAll -- 154 * Get all the available data at once. 155 * 156 * Results: 157 * A pointer to the data and the number of bytes available. 158 * 159 * Side Effects: 160 * None. 161 * 162 *----------------------------------------------------------------------- 163 */ 164 Byte * 165 Buf_GetAll (bp, numBytesPtr) 166 register Buffer bp; 167 int *numBytesPtr; 168 { 169 170 if (numBytesPtr != (int *)NULL) { 171 *numBytesPtr = bp->inPtr - bp->outPtr; 172 } 173 174 return (bp->outPtr); 175 } 176 177 /*- 178 *----------------------------------------------------------------------- 179 * Buf_Discard -- 180 * Throw away bytes in a buffer. 181 * 182 * Results: 183 * None. 184 * 185 * Side Effects: 186 * The bytes are discarded. 187 * 188 *----------------------------------------------------------------------- 189 */ 190 void 191 Buf_Discard (bp, numBytes) 192 register Buffer bp; 193 int numBytes; 194 { 195 196 if (bp->inPtr - bp->outPtr <= numBytes) { 197 bp->inPtr = bp->outPtr = bp->buffer; 198 bp->left = bp->size; 199 *bp->inPtr = 0; 200 } else { 201 bp->outPtr += numBytes; 202 } 203 } 204 205 /*- 206 *----------------------------------------------------------------------- 207 * Buf_Size -- 208 * Returns the number of bytes in the given buffer. Doesn't include 209 * the null-terminating byte. 210 * 211 * Results: 212 * The number of bytes. 213 * 214 * Side Effects: 215 * None. 216 * 217 *----------------------------------------------------------------------- 218 */ 219 int 220 Buf_Size (buf) 221 Buffer buf; 222 { 223 return (buf->inPtr - buf->outPtr); 224 } 225 226 /*- 227 *----------------------------------------------------------------------- 228 * Buf_Init -- 229 * Initialize a buffer. If no initial size is given, a reasonable 230 * default is used. 231 * 232 * Results: 233 * A buffer to be given to other functions in this library. 234 * 235 * Side Effects: 236 * The buffer is created, the space allocated and pointers 237 * initialized. 238 * 239 *----------------------------------------------------------------------- 240 */ 241 Buffer 242 Buf_Init (size) 243 int size; /* Initial size for the buffer */ 244 { 245 Buffer bp; /* New Buffer */ 246 247 bp = (Buffer)emalloc(sizeof(*bp)); 248 249 if (size <= 0) { 250 size = BUF_DEF_SIZE; 251 } 252 bp->left = bp->size = size; 253 bp->buffer = (Byte *)emalloc(size); 254 bp->inPtr = bp->outPtr = bp->buffer; 255 *bp->inPtr = 0; 256 257 return (bp); 258 } 259 260 /*- 261 *----------------------------------------------------------------------- 262 * Buf_Destroy -- 263 * Nuke a buffer and all its resources. 264 * 265 * Results: 266 * None. 267 * 268 * Side Effects: 269 * The buffer is freed. 270 * 271 *----------------------------------------------------------------------- 272 */ 273 void 274 Buf_Destroy (buf, freeData) 275 Buffer buf; /* Buffer to destroy */ 276 Boolean freeData; /* TRUE if the data should be destroyed as well */ 277 { 278 279 if (freeData) { 280 free ((char *)buf->buffer); 281 } 282 free ((char *)buf); 283 } 284 285 /*- 286 *----------------------------------------------------------------------- 287 * Buf_ReplaceLastByte -- 288 * Replace the last byte in a buffer. 289 * 290 * Results: 291 * None. 292 * 293 * Side Effects: 294 * If the buffer was empty intially, then a new byte will be added. 295 * Otherwise, the last byte is overwritten. 296 * 297 *----------------------------------------------------------------------- 298 */ 299 void 300 Buf_ReplaceLastByte (buf, byte) 301 Buffer buf; /* buffer to augment */ 302 int byte; /* byte to be written */ 303 { 304 if (buf->inPtr == buf->outPtr) 305 Buf_AddByte(buf, byte); 306 else 307 *(buf->inPtr - 1) = byte; 308 } 309