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