1236769Sobrien/* $NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $ */ 2236769Sobrien 3236769Sobrien/* 4236769Sobrien * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 5236769Sobrien * All rights reserved. 6236769Sobrien * 7236769Sobrien * This code is derived from software contributed to Berkeley by 8236769Sobrien * Adam de Boor. 9236769Sobrien * 10236769Sobrien * Redistribution and use in source and binary forms, with or without 11236769Sobrien * modification, are permitted provided that the following conditions 12236769Sobrien * are met: 13236769Sobrien * 1. Redistributions of source code must retain the above copyright 14236769Sobrien * notice, this list of conditions and the following disclaimer. 15236769Sobrien * 2. Redistributions in binary form must reproduce the above copyright 16236769Sobrien * notice, this list of conditions and the following disclaimer in the 17236769Sobrien * documentation and/or other materials provided with the distribution. 18236769Sobrien * 3. Neither the name of the University nor the names of its contributors 19236769Sobrien * may be used to endorse or promote products derived from this software 20236769Sobrien * without specific prior written permission. 21236769Sobrien * 22236769Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23236769Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24236769Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25236769Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26236769Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27236769Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28236769Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29236769Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30236769Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31236769Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32236769Sobrien * SUCH DAMAGE. 33236769Sobrien */ 34236769Sobrien 35236769Sobrien/* 36236769Sobrien * Copyright (c) 1988, 1989 by Adam de Boor 37236769Sobrien * Copyright (c) 1989 by Berkeley Softworks 38236769Sobrien * All rights reserved. 39236769Sobrien * 40236769Sobrien * This code is derived from software contributed to Berkeley by 41236769Sobrien * Adam de Boor. 42236769Sobrien * 43236769Sobrien * Redistribution and use in source and binary forms, with or without 44236769Sobrien * modification, are permitted provided that the following conditions 45236769Sobrien * are met: 46236769Sobrien * 1. Redistributions of source code must retain the above copyright 47236769Sobrien * notice, this list of conditions and the following disclaimer. 48236769Sobrien * 2. Redistributions in binary form must reproduce the above copyright 49236769Sobrien * notice, this list of conditions and the following disclaimer in the 50236769Sobrien * documentation and/or other materials provided with the distribution. 51236769Sobrien * 3. All advertising materials mentioning features or use of this software 52236769Sobrien * must display the following acknowledgement: 53236769Sobrien * This product includes software developed by the University of 54236769Sobrien * California, Berkeley and its contributors. 55236769Sobrien * 4. Neither the name of the University nor the names of its contributors 56236769Sobrien * may be used to endorse or promote products derived from this software 57236769Sobrien * without specific prior written permission. 58236769Sobrien * 59236769Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60236769Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61236769Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62236769Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63236769Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64236769Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65236769Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66236769Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67236769Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68236769Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69236769Sobrien * SUCH DAMAGE. 70236769Sobrien */ 71236769Sobrien 72236769Sobrien#ifndef MAKE_NATIVE 73236769Sobrienstatic char rcsid[] = "$NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $"; 74236769Sobrien#else 75236769Sobrien#include <sys/cdefs.h> 76236769Sobrien#ifndef lint 77236769Sobrien#if 0 78236769Sobrienstatic char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93"; 79236769Sobrien#else 80236769Sobrien__RCSID("$NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $"); 81236769Sobrien#endif 82236769Sobrien#endif /* not lint */ 83236769Sobrien#endif 84236769Sobrien 85236769Sobrien/*- 86236769Sobrien * buf.c -- 87236769Sobrien * Functions for automatically-expanded buffers. 88236769Sobrien */ 89236769Sobrien 90236769Sobrien#include "make.h" 91236769Sobrien#include "buf.h" 92236769Sobrien 93236769Sobrien#ifndef max 94236769Sobrien#define max(a,b) ((a) > (b) ? (a) : (b)) 95236769Sobrien#endif 96236769Sobrien 97236769Sobrien#define BUF_DEF_SIZE 256 /* Default buffer size */ 98236769Sobrien 99236769Sobrien/*- 100236769Sobrien *----------------------------------------------------------------------- 101236769Sobrien * Buf_Expand_1 -- 102236769Sobrien * Extend buffer for single byte add. 103236769Sobrien * 104236769Sobrien *----------------------------------------------------------------------- 105236769Sobrien */ 106236769Sobrienvoid 107236769SobrienBuf_Expand_1(Buffer *bp) 108236769Sobrien{ 109236769Sobrien bp->size += max(bp->size, 16); 110236769Sobrien bp->buffer = bmake_realloc(bp->buffer, bp->size); 111236769Sobrien} 112236769Sobrien 113236769Sobrien/*- 114236769Sobrien *----------------------------------------------------------------------- 115236769Sobrien * Buf_AddBytes -- 116236769Sobrien * Add a number of bytes to the buffer. 117236769Sobrien * 118236769Sobrien * Results: 119236769Sobrien * None. 120236769Sobrien * 121236769Sobrien * Side Effects: 122236769Sobrien * Guess what? 123236769Sobrien * 124236769Sobrien *----------------------------------------------------------------------- 125236769Sobrien */ 126236769Sobrienvoid 127236769SobrienBuf_AddBytes(Buffer *bp, int numBytes, const Byte *bytesPtr) 128236769Sobrien{ 129236769Sobrien int count = bp->count; 130236769Sobrien Byte *ptr; 131236769Sobrien 132236769Sobrien if (__predict_false(count + numBytes >= bp->size)) { 133236769Sobrien bp->size += max(bp->size, numBytes + 16); 134236769Sobrien bp->buffer = bmake_realloc(bp->buffer, bp->size); 135236769Sobrien } 136236769Sobrien 137236769Sobrien ptr = bp->buffer + count; 138236769Sobrien bp->count = count + numBytes; 139236769Sobrien ptr[numBytes] = 0; 140236769Sobrien memcpy(ptr, bytesPtr, numBytes); 141236769Sobrien} 142236769Sobrien 143236769Sobrien/*- 144236769Sobrien *----------------------------------------------------------------------- 145236769Sobrien * Buf_GetAll -- 146236769Sobrien * Get all the available data at once. 147236769Sobrien * 148236769Sobrien * Results: 149236769Sobrien * A pointer to the data and the number of bytes available. 150236769Sobrien * 151236769Sobrien * Side Effects: 152236769Sobrien * None. 153236769Sobrien * 154236769Sobrien *----------------------------------------------------------------------- 155236769Sobrien */ 156236769SobrienByte * 157236769SobrienBuf_GetAll(Buffer *bp, int *numBytesPtr) 158236769Sobrien{ 159236769Sobrien 160236769Sobrien if (numBytesPtr != NULL) 161236769Sobrien *numBytesPtr = bp->count; 162236769Sobrien 163236769Sobrien return (bp->buffer); 164236769Sobrien} 165236769Sobrien 166236769Sobrien/*- 167236769Sobrien *----------------------------------------------------------------------- 168236769Sobrien * Buf_Empty -- 169236769Sobrien * Throw away bytes in a buffer. 170236769Sobrien * 171236769Sobrien * Results: 172236769Sobrien * None. 173236769Sobrien * 174236769Sobrien * Side Effects: 175236769Sobrien * The bytes are discarded. 176236769Sobrien * 177236769Sobrien *----------------------------------------------------------------------- 178236769Sobrien */ 179236769Sobrienvoid 180236769SobrienBuf_Empty(Buffer *bp) 181236769Sobrien{ 182236769Sobrien 183236769Sobrien bp->count = 0; 184236769Sobrien *bp->buffer = 0; 185236769Sobrien} 186236769Sobrien 187236769Sobrien/*- 188236769Sobrien *----------------------------------------------------------------------- 189236769Sobrien * Buf_Init -- 190236769Sobrien * Initialize a buffer. If no initial size is given, a reasonable 191236769Sobrien * default is used. 192236769Sobrien * 193236769Sobrien * Input: 194236769Sobrien * size Initial size for the buffer 195236769Sobrien * 196236769Sobrien * Results: 197236769Sobrien * A buffer to be given to other functions in this library. 198236769Sobrien * 199236769Sobrien * Side Effects: 200236769Sobrien * The buffer is created, the space allocated and pointers 201236769Sobrien * initialized. 202236769Sobrien * 203236769Sobrien *----------------------------------------------------------------------- 204236769Sobrien */ 205236769Sobrienvoid 206236769SobrienBuf_Init(Buffer *bp, int size) 207236769Sobrien{ 208236769Sobrien if (size <= 0) { 209236769Sobrien size = BUF_DEF_SIZE; 210236769Sobrien } 211236769Sobrien bp->size = size; 212236769Sobrien bp->count = 0; 213236769Sobrien bp->buffer = bmake_malloc(size); 214236769Sobrien *bp->buffer = 0; 215236769Sobrien} 216236769Sobrien 217236769Sobrien/*- 218236769Sobrien *----------------------------------------------------------------------- 219236769Sobrien * Buf_Destroy -- 220236769Sobrien * Nuke a buffer and all its resources. 221236769Sobrien * 222236769Sobrien * Input: 223236769Sobrien * buf Buffer to destroy 224236769Sobrien * freeData TRUE if the data should be destroyed 225236769Sobrien * 226236769Sobrien * Results: 227236769Sobrien * Data buffer, NULL if freed 228236769Sobrien * 229236769Sobrien * Side Effects: 230236769Sobrien * The buffer is freed. 231236769Sobrien * 232236769Sobrien *----------------------------------------------------------------------- 233236769Sobrien */ 234236769SobrienByte * 235236769SobrienBuf_Destroy(Buffer *buf, Boolean freeData) 236236769Sobrien{ 237236769Sobrien Byte *data; 238236769Sobrien 239236769Sobrien data = buf->buffer; 240236769Sobrien if (freeData) { 241236769Sobrien free(data); 242236769Sobrien data = NULL; 243236769Sobrien } 244236769Sobrien 245236769Sobrien buf->size = 0; 246236769Sobrien buf->count = 0; 247236769Sobrien buf->buffer = NULL; 248236769Sobrien 249236769Sobrien return data; 250236769Sobrien} 251236769Sobrien 252236769Sobrien 253236769Sobrien/*- 254236769Sobrien *----------------------------------------------------------------------- 255236769Sobrien * Buf_DestroyCompact -- 256236769Sobrien * Nuke a buffer and return its data. 257236769Sobrien * 258236769Sobrien * Input: 259236769Sobrien * buf Buffer to destroy 260236769Sobrien * 261236769Sobrien * Results: 262236769Sobrien * Data buffer 263236769Sobrien * 264236769Sobrien * Side Effects: 265236769Sobrien * If the buffer size is much greater than its content, 266236769Sobrien * a new buffer will be allocated and the old one freed. 267236769Sobrien * 268236769Sobrien *----------------------------------------------------------------------- 269236769Sobrien */ 270236769Sobrien#ifndef BUF_COMPACT_LIMIT 271236769Sobrien# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */ 272236769Sobrien#endif 273236769Sobrien 274236769SobrienByte * 275236769SobrienBuf_DestroyCompact(Buffer *buf) 276236769Sobrien{ 277236769Sobrien#if BUF_COMPACT_LIMIT > 0 278236769Sobrien Byte *data; 279236769Sobrien 280236769Sobrien if (buf->size - buf->count >= BUF_COMPACT_LIMIT) { 281236769Sobrien /* We trust realloc to be smart */ 282236769Sobrien data = bmake_realloc(buf->buffer, buf->count + 1); 283236769Sobrien if (data) { 284236769Sobrien data[buf->count] = 0; 285236769Sobrien Buf_Destroy(buf, FALSE); 286236769Sobrien return data; 287236769Sobrien } 288236769Sobrien } 289236769Sobrien#endif 290236769Sobrien return Buf_Destroy(buf, FALSE); 291236769Sobrien} 292