1 /* $NetBSD: buf.c,v 1.13 2002/06/15 18:24:55 wiz 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.13 2002/06/15 18:24:55 wiz 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.13 2002/06/15 18:24:55 wiz 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(Buffer bp, int byte) 103 { 104 int nbytes = 1; 105 bp->left = 0; 106 BufExpand (bp, nbytes); 107 108 *bp->inPtr++ = byte; 109 bp->left--; 110 111 /* 112 * Null-terminate 113 */ 114 *bp->inPtr = 0; 115 } 116 117 /*- 118 *----------------------------------------------------------------------- 119 * Buf_AddBytes -- 120 * Add a number of bytes to the buffer. 121 * 122 * Results: 123 * None. 124 * 125 * Side Effects: 126 * Guess what? 127 * 128 *----------------------------------------------------------------------- 129 */ 130 void 131 Buf_AddBytes(Buffer bp, int numBytes, const Byte *bytesPtr) 132 { 133 134 BufExpand (bp, numBytes); 135 136 memcpy (bp->inPtr, bytesPtr, numBytes); 137 bp->inPtr += numBytes; 138 bp->left -= numBytes; 139 140 /* 141 * Null-terminate 142 */ 143 *bp->inPtr = 0; 144 } 145 146 /*- 147 *----------------------------------------------------------------------- 148 * Buf_GetAll -- 149 * Get all the available data at once. 150 * 151 * Results: 152 * A pointer to the data and the number of bytes available. 153 * 154 * Side Effects: 155 * None. 156 * 157 *----------------------------------------------------------------------- 158 */ 159 Byte * 160 Buf_GetAll(Buffer bp, int *numBytesPtr) 161 { 162 163 if (numBytesPtr != (int *)NULL) { 164 *numBytesPtr = bp->inPtr - bp->outPtr; 165 } 166 167 return (bp->outPtr); 168 } 169 170 /*- 171 *----------------------------------------------------------------------- 172 * Buf_Discard -- 173 * Throw away bytes in a buffer. 174 * 175 * Results: 176 * None. 177 * 178 * Side Effects: 179 * The bytes are discarded. 180 * 181 *----------------------------------------------------------------------- 182 */ 183 void 184 Buf_Discard(Buffer bp, int numBytes) 185 { 186 187 if (bp->inPtr - bp->outPtr <= numBytes) { 188 bp->inPtr = bp->outPtr = bp->buffer; 189 bp->left = bp->size; 190 *bp->inPtr = 0; 191 } else { 192 bp->outPtr += numBytes; 193 } 194 } 195 196 /*- 197 *----------------------------------------------------------------------- 198 * Buf_Size -- 199 * Returns the number of bytes in the given buffer. Doesn't include 200 * the null-terminating byte. 201 * 202 * Results: 203 * The number of bytes. 204 * 205 * Side Effects: 206 * None. 207 * 208 *----------------------------------------------------------------------- 209 */ 210 int 211 Buf_Size(Buffer buf) 212 { 213 return (buf->inPtr - buf->outPtr); 214 } 215 216 /*- 217 *----------------------------------------------------------------------- 218 * Buf_Init -- 219 * Initialize a buffer. If no initial size is given, a reasonable 220 * default is used. 221 * 222 * Input: 223 * size Initial size for the buffer 224 * 225 * Results: 226 * A buffer to be given to other functions in this library. 227 * 228 * Side Effects: 229 * The buffer is created, the space allocated and pointers 230 * initialized. 231 * 232 *----------------------------------------------------------------------- 233 */ 234 Buffer 235 Buf_Init(int size) 236 { 237 Buffer bp; /* New Buffer */ 238 239 bp = (Buffer)emalloc(sizeof(*bp)); 240 241 if (size <= 0) { 242 size = BUF_DEF_SIZE; 243 } 244 bp->left = bp->size = size; 245 bp->buffer = (Byte *)emalloc(size); 246 bp->inPtr = bp->outPtr = bp->buffer; 247 *bp->inPtr = 0; 248 249 return (bp); 250 } 251 252 /*- 253 *----------------------------------------------------------------------- 254 * Buf_Destroy -- 255 * Nuke a buffer and all its resources. 256 * 257 * Input: 258 * buf Buffer to destroy 259 * freeData TRUE if the data should be destroyed 260 * 261 * Results: 262 * None. 263 * 264 * Side Effects: 265 * The buffer is freed. 266 * 267 *----------------------------------------------------------------------- 268 */ 269 void 270 Buf_Destroy(Buffer buf, Boolean freeData) 271 { 272 273 if (freeData) { 274 free ((char *)buf->buffer); 275 } 276 free ((char *)buf); 277 } 278 279 /*- 280 *----------------------------------------------------------------------- 281 * Buf_ReplaceLastByte -- 282 * Replace the last byte in a buffer. 283 * 284 * Input: 285 * buf buffer to augment 286 * byte byte to be written 287 * 288 * Results: 289 * None. 290 * 291 * Side Effects: 292 * If the buffer was empty intially, then a new byte will be added. 293 * Otherwise, the last byte is overwritten. 294 * 295 *----------------------------------------------------------------------- 296 */ 297 void 298 Buf_ReplaceLastByte(Buffer buf, int byte) 299 { 300 if (buf->inPtr == buf->outPtr) 301 Buf_AddByte(buf, byte); 302 else 303 *(buf->inPtr - 1) = byte; 304 } 305