]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libxo/libxo/xo_buf.h
Integrate capsicum-test into the FreeBSD test suite
[FreeBSD/FreeBSD.git] / contrib / libxo / libxo / xo_buf.h
1 /*
2  * Copyright (c) 2015, Juniper Networks, Inc.
3  * All rights reserved.
4  * This SOFTWARE is licensed under the LICENSE provided in the
5  * ../Copyright file. By downloading, installing, copying, or otherwise
6  * using the SOFTWARE, you agree to be bound by the terms of that
7  * LICENSE.
8  * Phil Shafer, August 2015
9  */
10
11 /*
12  * This file is an _internal_ part of the libxo plumbing, not suitable
13  * for external use.  It is not considered part of the libxo API and
14  * will not be a stable part of that API.  Mine, not your's, dude...
15  * The real hope is that something like this will become a standard part
16  * of libc and I can kill this off.
17  */
18
19 #ifndef XO_BUF_H
20 #define XO_BUF_H
21
22 #define XO_BUFSIZ               (8*1024) /* Initial buffer size */
23 #define XO_BUF_HIGH_WATER       (XO_BUFSIZ - 512) /* When to auto-flush */
24 /*
25  * xo_buffer_t: a memory buffer that can be grown as needed.  We
26  * use them for building format strings and output data.
27  */
28 typedef struct xo_buffer_s {
29     char *xb_bufp;              /* Buffer memory */
30     char *xb_curp;              /* Current insertion point */
31     ssize_t xb_size;            /* Size of buffer */
32 } xo_buffer_t;
33
34 /*
35  * Initialize the contents of an xo_buffer_t.
36  */
37 static inline void
38 xo_buf_init (xo_buffer_t *xbp)
39 {
40     xbp->xb_size = XO_BUFSIZ;
41     xbp->xb_bufp = xo_realloc(NULL, xbp->xb_size);
42     xbp->xb_curp = xbp->xb_bufp;
43 }
44
45 /*
46  * Reset the buffer to empty
47  */
48 static inline void
49 xo_buf_reset (xo_buffer_t *xbp)
50 {
51     xbp->xb_curp = xbp->xb_bufp;
52 }
53
54 /*
55  * Return the number of bytes left in the buffer
56  */
57 static inline int
58 xo_buf_left (xo_buffer_t *xbp)
59 {
60     return xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp);
61 }
62
63 /*
64  * See if the buffer to empty
65  */
66 static inline int
67 xo_buf_is_empty (xo_buffer_t *xbp)
68 {
69     return (xbp->xb_curp == xbp->xb_bufp);
70 }
71
72 /*
73  * Return the current offset
74  */
75 static inline unsigned
76 xo_buf_offset (xo_buffer_t *xbp)
77 {
78     return xbp ? (xbp->xb_curp - xbp->xb_bufp) : 0;
79 }
80
81 static inline char *
82 xo_buf_data (xo_buffer_t *xbp, unsigned offset)
83 {
84     if (xbp == NULL)
85         return NULL;
86     return xbp->xb_bufp + offset;
87 }
88
89 static inline char *
90 xo_buf_cur (xo_buffer_t *xbp)
91 {
92     if (xbp == NULL)
93         return NULL;
94     return xbp->xb_curp;
95 }
96
97 /*
98  * Initialize the contents of an xo_buffer_t.
99  */
100 static inline void
101 xo_buf_cleanup (xo_buffer_t *xbp)
102 {
103     if (xbp->xb_bufp)
104         xo_free(xbp->xb_bufp);
105     bzero(xbp, sizeof(*xbp));
106 }
107
108 /*
109  * Does the buffer have room for the given number of bytes of data?
110  * If not, realloc the buffer to make room.  If that fails, we
111  * return 0 to tell the caller they are in trouble.
112  */
113 static inline int
114 xo_buf_has_room (xo_buffer_t *xbp, ssize_t len)
115 {
116     if (xbp->xb_curp + len >= xbp->xb_bufp + xbp->xb_size) {
117         ssize_t sz = xbp->xb_size + XO_BUFSIZ;
118         char *bp = xo_realloc(xbp->xb_bufp, sz);
119         if (bp == NULL)
120             return 0;
121
122         xbp->xb_curp = bp + (xbp->xb_curp - xbp->xb_bufp);
123         xbp->xb_bufp = bp;
124         xbp->xb_size = sz;
125     }
126
127     return 1;
128 }
129
130 /*
131  * Append the given string to the given buffer
132  */
133 static inline void
134 xo_buf_append (xo_buffer_t *xbp, const char *str, ssize_t len)
135 {
136     if (str == NULL || len == 0 || !xo_buf_has_room(xbp, len))
137         return;
138
139     memcpy(xbp->xb_curp, str, len);
140     xbp->xb_curp += len;
141 }
142
143 /*
144  * Append the given NUL-terminated string to the given buffer
145  */
146 static inline void
147 xo_buf_append_str (xo_buffer_t *xbp, const char *str)
148 {
149     ssize_t len = strlen(str);
150
151     if (!xo_buf_has_room(xbp, len))
152         return;
153
154     memcpy(xbp->xb_curp, str, len);
155     xbp->xb_curp += len;
156 }
157
158 #endif /* XO_BUF_H */