buf.c revision 141138
1114402Sru/*- 2114402Sru * Copyright (c) 1988, 1989, 1990, 1993 3114402Sru * The Regents of the University of California. All rights reserved. 4114402Sru * Copyright (c) 1988, 1989 by Adam de Boor 5114402Sru * Copyright (c) 1989 by Berkeley Softworks 6114402Sru * All rights reserved. 7114402Sru * 8114402Sru * This code is derived from software contributed to Berkeley by 9114402Sru * Adam de Boor. 10114402Sru * 11114402Sru * Redistribution and use in source and binary forms, with or without 12114402Sru * modification, are permitted provided that the following conditions 13114402Sru * are met: 14114402Sru * 1. Redistributions of source code must retain the above copyright 15114402Sru * notice, this list of conditions and the following disclaimer. 16114402Sru * 2. Redistributions in binary form must reproduce the above copyright 17114402Sru * notice, this list of conditions and the following disclaimer in the 18114402Sru * documentation and/or other materials provided with the distribution. 19151497Sru * 3. All advertising materials mentioning features or use of this software 20114402Sru * must display the following acknowledgement: 21114402Sru * This product includes software developed by the University of 22114402Sru * California, Berkeley and its contributors. 23114402Sru * 4. Neither the name of the University nor the names of its contributors 24114402Sru * may be used to endorse or promote products derived from this software 25114402Sru * without specific prior written permission. 26114402Sru * 27114402Sru * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28114402Sru * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29114402Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30114402Sru * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31114402Sru * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32114402Sru * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33114402Sru * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34114402Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35114402Sru * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36114402Sru * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37114402Sru * SUCH DAMAGE. 38114402Sru * 39114402Sru * @(#)buf.c 8.1 (Berkeley) 6/6/93 40114402Sru */ 41114402Sru 42114402Sru#include <sys/cdefs.h> 43114402Sru__FBSDID("$FreeBSD: head/usr.bin/make/buf.c 141138 2005-02-02 11:21:26Z harti $"); 44114402Sru 45114402Sru/*- 46114402Sru * buf.c -- 47114402Sru * Functions for automatically-expanded buffers. 48114402Sru */ 49114402Sru 50114402Sru#include <string.h> 51114402Sru#include <stdlib.h> 52114402Sru 53114402Sru#include "buf.h" 54114402Sru#include "sprite.h" 55114402Sru#include "util.h" 56114402Sru 57114402Sru#ifndef max 58114402Sru#define max(a,b) ((a) > (b) ? (a) : (b)) 59114402Sru#endif 60114402Sru 61114402Sru/* 62114402Sru * BufExpand -- 63114402Sru * Expand the given buffer to hold the given number of additional 64114402Sru * bytes. 65114402Sru * Makes sure there's room for an extra NULL byte at the end of the 66114402Sru * buffer in case it holds a string. 67114402Sru */ 68114402Sru#define BufExpand(bp, nb) do { \ 69114402Sru if ((bp)->left < (nb) + 1) { \ 70114402Sru int newSize = (bp)->size + max((nb) + 1, BUF_ADD_INC); \ 71114402Sru Byte *newBuf = erealloc((bp)->buffer, newSize); \ 72114402Sru \ 73114402Sru (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \ 74114402Sru (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer); \ 75114402Sru (bp)->buffer = newBuf; \ 76114402Sru (bp)->size = newSize; \ 77114402Sru (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer); \ 78114402Sru } \ 79114402Sru } while (0) 80114402Sru 81114402Sru#define BUF_DEF_SIZE 256 /* Default buffer size */ 82114402Sru#define BUF_ADD_INC 256 /* Expansion increment when Adding */ 83114402Sru#define BUF_UNGET_INC 16 /* Expansion increment when Ungetting */ 84114402Sru 85114402Sru/*- 86114402Sru *----------------------------------------------------------------------- 87114402Sru * Buf_OvAddByte -- 88114402Sru * Add a single byte to the buffer. left is zero or negative. 89114402Sru * 90114402Sru * Results: 91114402Sru * None. 92114402Sru * 93114402Sru * Side Effects: 94114402Sru * The buffer may be expanded. 95114402Sru * 96114402Sru *----------------------------------------------------------------------- 97114402Sru */ 98114402Sruvoid 99114402SruBuf_OvAddByte(Buffer *bp, Byte byte) 100114402Sru{ 101114402Sru 102114402Sru bp->left = 0; 103114402Sru BufExpand(bp, 1); 104114402Sru 105114402Sru *bp->inPtr++ = byte; 106114402Sru bp->left--; 107114402Sru 108114402Sru /* 109114402Sru * Null-terminate 110114402Sru */ 111114402Sru *bp->inPtr = 0; 112114402Sru} 113114402Sru 114114402Sru/*- 115114402Sru *----------------------------------------------------------------------- 116114402Sru * Buf_AddBytes -- 117114402Sru * Add a number of bytes to the buffer. 118114402Sru * 119114402Sru * Results: 120114402Sru * None. 121114402Sru * 122114402Sru * Side Effects: 123114402Sru * Guess what? 124114402Sru * 125114402Sru *----------------------------------------------------------------------- 126114402Sru */ 127114402Sruvoid 128114402SruBuf_AddBytes(Buffer *bp, size_t numBytes, const Byte *bytesPtr) 129114402Sru{ 130114402Sru 131114402Sru BufExpand(bp, numBytes); 132114402Sru 133114402Sru memcpy(bp->inPtr, bytesPtr, numBytes); 134114402Sru bp->inPtr += numBytes; 135114402Sru bp->left -= numBytes; 136114402Sru 137114402Sru /* 138 * Null-terminate 139 */ 140 *bp->inPtr = 0; 141} 142 143/*- 144 *----------------------------------------------------------------------- 145 * Buf_GetAll -- 146 * Get all the available data at once. 147 * 148 * Results: 149 * A pointer to the data and the number of bytes available. 150 * 151 * Side Effects: 152 * None. 153 * 154 *----------------------------------------------------------------------- 155 */ 156Byte * 157Buf_GetAll(Buffer *bp, size_t *numBytesPtr) 158{ 159 160 if (numBytesPtr != NULL) 161 *numBytesPtr = bp->inPtr - bp->outPtr; 162 163 return (bp->outPtr); 164} 165 166/*- 167 *----------------------------------------------------------------------- 168 * Buf_Discard -- 169 * Throw away bytes in a buffer. 170 * 171 * Results: 172 * None. 173 * 174 * Side Effects: 175 * The bytes are discarded. 176 * 177 *----------------------------------------------------------------------- 178 */ 179void 180Buf_Discard(Buffer *bp, size_t numBytes) 181{ 182 183 if ((size_t)(bp->inPtr - bp->outPtr) <= numBytes) { 184 bp->inPtr = bp->outPtr = bp->buffer; 185 bp->left = bp->size; 186 *bp->inPtr = 0; 187 } else 188 bp->outPtr += numBytes; 189} 190 191/*- 192 *----------------------------------------------------------------------- 193 * Buf_Size -- 194 * Returns the number of bytes in the given buffer. Doesn't include 195 * the null-terminating byte. 196 * 197 * Results: 198 * The number of bytes. 199 * 200 * Side Effects: 201 * None. 202 * 203 *----------------------------------------------------------------------- 204 */ 205size_t 206Buf_Size(Buffer *buf) 207{ 208 209 return (buf->inPtr - buf->outPtr); 210} 211 212/*- 213 *----------------------------------------------------------------------- 214 * Buf_Init -- 215 * Initialize a buffer. If no initial size is given, a reasonable 216 * default is used. 217 * 218 * Results: 219 * A buffer to be given to other functions in this library. 220 * 221 * Side Effects: 222 * The buffer is created, the space allocated and pointers 223 * initialized. 224 * 225 *----------------------------------------------------------------------- 226 */ 227Buffer * 228Buf_Init(size_t size) 229{ 230 Buffer *bp; /* New Buffer */ 231 232 bp = emalloc(sizeof(*bp)); 233 234 if (size <= 0) 235 size = BUF_DEF_SIZE; 236 237 bp->left = bp->size = size; 238 bp->buffer = emalloc(size); 239 bp->inPtr = bp->outPtr = bp->buffer; 240 *bp->inPtr = 0; 241 242 return (bp); 243} 244 245/*- 246 *----------------------------------------------------------------------- 247 * Buf_Destroy -- 248 * Destroy a buffer, and optionally free its data, too. 249 * 250 * Results: 251 * None. 252 * 253 * Side Effects: 254 * The buffer is freed. 255 * 256 *----------------------------------------------------------------------- 257 */ 258void 259Buf_Destroy(Buffer *buf, Boolean freeData) 260{ 261 262 if (freeData) 263 free(buf->buffer); 264 free(buf); 265} 266 267/*- 268 *----------------------------------------------------------------------- 269 * Buf_ReplaceLastByte -- 270 * Replace the last byte in a buffer. 271 * 272 * Results: 273 * None. 274 * 275 * Side Effects: 276 * If the buffer was empty intially, then a new byte will be added. 277 * Otherwise, the last byte is overwritten. 278 * 279 *----------------------------------------------------------------------- 280 */ 281void 282Buf_ReplaceLastByte(Buffer *buf, Byte byte) 283{ 284 if (buf->inPtr == buf->outPtr) 285 Buf_AddByte(buf, byte); 286 else 287 *(buf->inPtr - 1) = byte; 288} 289