1*5ae330e2SDavid van Moolenbroek /* $NetBSD: buffer.h,v 1.4 2008/04/28 20:24:12 martin Exp $ */
2*5ae330e2SDavid van Moolenbroek
3*5ae330e2SDavid van Moolenbroek /*-
4*5ae330e2SDavid van Moolenbroek * Copyright (c) 2005 The NetBSD Foundation, Inc.
5*5ae330e2SDavid van Moolenbroek * All rights reserved.
6*5ae330e2SDavid van Moolenbroek *
7*5ae330e2SDavid van Moolenbroek * This code is derived from software contributed to The NetBSD Foundation
8*5ae330e2SDavid van Moolenbroek * by Christos Zoulas.
9*5ae330e2SDavid van Moolenbroek *
10*5ae330e2SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
11*5ae330e2SDavid van Moolenbroek * modification, are permitted provided that the following conditions
12*5ae330e2SDavid van Moolenbroek * are met:
13*5ae330e2SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
14*5ae330e2SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
15*5ae330e2SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
16*5ae330e2SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
17*5ae330e2SDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
18*5ae330e2SDavid van Moolenbroek *
19*5ae330e2SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*5ae330e2SDavid van Moolenbroek * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*5ae330e2SDavid van Moolenbroek * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*5ae330e2SDavid van Moolenbroek * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*5ae330e2SDavid van Moolenbroek * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*5ae330e2SDavid van Moolenbroek * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*5ae330e2SDavid van Moolenbroek * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*5ae330e2SDavid van Moolenbroek * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*5ae330e2SDavid van Moolenbroek * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*5ae330e2SDavid van Moolenbroek * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*5ae330e2SDavid van Moolenbroek * POSSIBILITY OF SUCH DAMAGE.
30*5ae330e2SDavid van Moolenbroek */
31*5ae330e2SDavid van Moolenbroek
32*5ae330e2SDavid van Moolenbroek #include <stddef.h>
33*5ae330e2SDavid van Moolenbroek #include <stdio.h>
34*5ae330e2SDavid van Moolenbroek #include <stdlib.h>
35*5ae330e2SDavid van Moolenbroek #include <err.h>
36*5ae330e2SDavid van Moolenbroek
37*5ae330e2SDavid van Moolenbroek #define BUF_SIZE BUFSIZ
38*5ae330e2SDavid van Moolenbroek struct buffer {
39*5ae330e2SDavid van Moolenbroek char *ptr;
40*5ae330e2SDavid van Moolenbroek char *bptr;
41*5ae330e2SDavid van Moolenbroek char *eptr;
42*5ae330e2SDavid van Moolenbroek };
43*5ae330e2SDavid van Moolenbroek
44*5ae330e2SDavid van Moolenbroek static void
buf_init(struct buffer * buf)45*5ae330e2SDavid van Moolenbroek buf_init(struct buffer *buf)
46*5ae330e2SDavid van Moolenbroek {
47*5ae330e2SDavid van Moolenbroek buf->ptr = buf->bptr = malloc(BUF_SIZE);
48*5ae330e2SDavid van Moolenbroek if (buf->ptr == NULL)
49*5ae330e2SDavid van Moolenbroek err(1, "Cannot allocate buffer");
50*5ae330e2SDavid van Moolenbroek buf->eptr = buf->ptr + BUF_SIZE;
51*5ae330e2SDavid van Moolenbroek }
52*5ae330e2SDavid van Moolenbroek
53*5ae330e2SDavid van Moolenbroek static void
buf_end(struct buffer * buf)54*5ae330e2SDavid van Moolenbroek buf_end(struct buffer *buf)
55*5ae330e2SDavid van Moolenbroek {
56*5ae330e2SDavid van Moolenbroek free(buf->bptr);
57*5ae330e2SDavid van Moolenbroek }
58*5ae330e2SDavid van Moolenbroek
59*5ae330e2SDavid van Moolenbroek static void
buf_grow(struct buffer * buf,size_t minsize)60*5ae330e2SDavid van Moolenbroek buf_grow(struct buffer *buf, size_t minsize)
61*5ae330e2SDavid van Moolenbroek {
62*5ae330e2SDavid van Moolenbroek ptrdiff_t diff;
63*5ae330e2SDavid van Moolenbroek size_t len = (buf->eptr - buf->bptr) +
64*5ae330e2SDavid van Moolenbroek (minsize > BUF_SIZE ? minsize : BUF_SIZE);
65*5ae330e2SDavid van Moolenbroek char *nptr = realloc(buf->bptr, len);
66*5ae330e2SDavid van Moolenbroek
67*5ae330e2SDavid van Moolenbroek if (nptr == NULL)
68*5ae330e2SDavid van Moolenbroek err(1, "Cannot grow buffer");
69*5ae330e2SDavid van Moolenbroek
70*5ae330e2SDavid van Moolenbroek if (nptr == buf->bptr) {
71*5ae330e2SDavid van Moolenbroek buf->eptr = buf->bptr + len;
72*5ae330e2SDavid van Moolenbroek return;
73*5ae330e2SDavid van Moolenbroek }
74*5ae330e2SDavid van Moolenbroek
75*5ae330e2SDavid van Moolenbroek diff = nptr - buf->bptr;
76*5ae330e2SDavid van Moolenbroek buf->bptr += diff;
77*5ae330e2SDavid van Moolenbroek buf->eptr = buf->bptr + len;
78*5ae330e2SDavid van Moolenbroek buf->ptr += diff;
79*5ae330e2SDavid van Moolenbroek }
80*5ae330e2SDavid van Moolenbroek
81*5ae330e2SDavid van Moolenbroek static inline void
buf_putc(struct buffer * buf,char c)82*5ae330e2SDavid van Moolenbroek buf_putc(struct buffer *buf, char c)
83*5ae330e2SDavid van Moolenbroek {
84*5ae330e2SDavid van Moolenbroek if (buf->ptr >= buf->eptr)
85*5ae330e2SDavid van Moolenbroek buf_grow(buf, 1);
86*5ae330e2SDavid van Moolenbroek *buf->ptr++ = c;
87*5ae330e2SDavid van Moolenbroek }
88*5ae330e2SDavid van Moolenbroek
89*5ae330e2SDavid van Moolenbroek static inline void
buf_reset(struct buffer * buf)90*5ae330e2SDavid van Moolenbroek buf_reset(struct buffer *buf)
91*5ae330e2SDavid van Moolenbroek {
92*5ae330e2SDavid van Moolenbroek buf->ptr = buf->bptr;
93*5ae330e2SDavid van Moolenbroek }
94*5ae330e2SDavid van Moolenbroek
95*5ae330e2SDavid van Moolenbroek static inline char
buf_unputc(struct buffer * buf)96*5ae330e2SDavid van Moolenbroek buf_unputc(struct buffer *buf)
97*5ae330e2SDavid van Moolenbroek {
98*5ae330e2SDavid van Moolenbroek return buf->ptr > buf->bptr ? *--buf->ptr : '\0';
99*5ae330e2SDavid van Moolenbroek }
100