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