The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
buf.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/**
19 * $Id: deae54c1bda80d1163fabb64e8db5e53373a10cb $
20 * @file lib/bio/buf.h
21 * @brief Binary IO abstractions for buffers
22 *
23 * The #fr_bio_buf_t allows readers and writers to use a shared buffer, without overflow.
24 *
25 * @copyright 2024 Network RADIUS SAS (legal@networkradius.com)
26 */
27RCSIDH(lib_bio_buf_h, "$Id: deae54c1bda80d1163fabb64e8db5e53373a10cb $")
28
29typedef struct {
30 uint8_t *start; //!< start of the buffer
31 uint8_t *end; //!< end of the buffer
32
33 uint8_t *read; //!< where in the buffer reads are taken from
34 uint8_t *write; //!< where in the buffer writes are sent to
36
37static inline void fr_bio_buf_init(fr_bio_buf_t *bio_buf, uint8_t *buffer, size_t size)
38{
39 bio_buf->start = bio_buf->read = bio_buf->write = buffer;
40 bio_buf->end = buffer + size;
41}
42
43size_t fr_bio_buf_make_room(fr_bio_buf_t *bio_buf);
44
45size_t fr_bio_buf_read(fr_bio_buf_t *bio_buf, void *buffer, size_t size) CC_HINT(nonnull(1));
46ssize_t fr_bio_buf_write(fr_bio_buf_t *bio_buf, const void *buffer, size_t size) CC_HINT(nonnull);
47
48
49#ifndef NDEBUG
50static inline void CC_HINT(nonnull) fr_bio_buf_verify(fr_bio_buf_t const *bio_buf)
51{
52 fr_assert(bio_buf->start != NULL);
53 fr_assert(bio_buf->start <= bio_buf->read);
54 fr_assert(bio_buf->read <= bio_buf->write);
55 fr_assert(bio_buf->write <= bio_buf->end);
56}
57#else
58#define fr_bio_buf_verify(_x)
59#endif
60
61static inline void CC_HINT(nonnull) fr_bio_buf_reset(fr_bio_buf_t *bio_buf)
62{
63 fr_bio_buf_verify(bio_buf);
64
65 bio_buf->read = bio_buf->write = bio_buf->start;
66}
67
68static inline bool CC_HINT(nonnull) fr_bio_buf_initialized(fr_bio_buf_t const *bio_buf)
69{
70 return (bio_buf->start != NULL);
71}
72
73static inline size_t CC_HINT(nonnull) fr_bio_buf_used(fr_bio_buf_t const *bio_buf)
74{
75 if (!fr_bio_buf_initialized(bio_buf)) return 0;
76
77 fr_bio_buf_verify(bio_buf);
78
79 return (bio_buf->write - bio_buf->read);
80}
81
82static inline size_t CC_HINT(nonnull) fr_bio_buf_write_room(fr_bio_buf_t const *bio_buf)
83{
84 fr_bio_buf_verify(bio_buf);
85
86 return bio_buf->end - bio_buf->write;
87}
88
89static inline uint8_t *CC_HINT(nonnull) fr_bio_buf_write_reserve(fr_bio_buf_t *bio_buf, size_t size)
90{
91 fr_bio_buf_verify(bio_buf);
92
93 if (fr_bio_buf_write_room(bio_buf) < size) return NULL;
94
95 return bio_buf->write;
96}
97
98static inline int CC_HINT(nonnull) fr_bio_buf_write_alloc(fr_bio_buf_t *bio_buf, size_t size)
99{
100 fr_bio_buf_verify(bio_buf);
101
102 if (fr_bio_buf_write_room(bio_buf) < size) return -1;
103
104 bio_buf->write += size;
105
106 fr_bio_buf_verify(bio_buf);
107
108 return 0;
109}
110
111static inline void CC_HINT(nonnull) fr_bio_buf_write_undo(fr_bio_buf_t *bio_buf, size_t size)
112{
113 fr_bio_buf_verify(bio_buf);
114
115 fr_assert(bio_buf->read + size <= bio_buf->write);
116
117 bio_buf->write -= size;
118 fr_bio_buf_verify(bio_buf);
119
120 if (bio_buf->read == bio_buf->write) {
121 fr_bio_buf_reset(bio_buf);
122 }
123}
124
125static inline bool fr_bio_buf_contains(fr_bio_buf_t *bio_buf, void const *buffer)
126{
127 return ((uint8_t const *) buffer >= bio_buf->start) && ((uint8_t const *) buffer <= bio_buf->end);
128}
129
130#if 0
131static inline void CC_HINT(nonnull) fr_bio_buf_write_update(fr_bio_buf_t *bio_buf, void const *buffer, size_t size, size_t written)
132{
133 if (!fr_bio_buf_initialized(bio_buf)) return;
134
135 fr_bio_buf_verify(bio_buf);
136
137 if (bio_buf->read == buffer) {
138 fr_assert(fr_bio_buf_used(bio_buf) >= size);
139
140 (void) fr_bio_buf_read(bio_buf, NULL, written);
141 } else {
142 /*
143 * If we're not writing from the start of write_buffer, then the data to
144 * be written CANNOT appear anywhere in the buffer.
145 */
147 }
148}
149#endif
150
151static inline size_t CC_HINT(nonnull) fr_bio_buf_size(fr_bio_buf_t const *bio_buf)
152{
153 fr_bio_buf_verify(bio_buf);
154
155 return (bio_buf->end - bio_buf->start);
156}
157
158int fr_bio_buf_alloc(TALLOC_CTX *ctx, fr_bio_buf_t *bio_buf, size_t size) CC_HINT(nonnull);
static int const char char buffer[256]
Definition acutest.h:576
static bool fr_bio_buf_initialized(fr_bio_buf_t const *bio_buf)
Definition buf.h:68
static bool fr_bio_buf_contains(fr_bio_buf_t *bio_buf, void const *buffer)
Definition buf.h:125
size_t fr_bio_buf_read(fr_bio_buf_t *bio_buf, void *buffer, size_t size))
Definition buf.c:45
static void fr_bio_buf_init(fr_bio_buf_t *bio_buf, uint8_t *buffer, size_t size)
Definition buf.h:37
size_t fr_bio_buf_make_room(fr_bio_buf_t *bio_buf)
Definition buf.c:28
static size_t fr_bio_buf_write_room(fr_bio_buf_t const *bio_buf)
Definition buf.h:82
uint8_t * start
start of the buffer
Definition buf.h:30
static size_t fr_bio_buf_used(fr_bio_buf_t const *bio_buf)
Definition buf.h:73
uint8_t * end
end of the buffer
Definition buf.h:31
static void fr_bio_buf_reset(fr_bio_buf_t *bio_buf)
Definition buf.h:61
static void fr_bio_buf_verify(fr_bio_buf_t const *bio_buf)
Definition buf.h:50
static uint8_t * fr_bio_buf_write_reserve(fr_bio_buf_t *bio_buf, size_t size)
Definition buf.h:89
uint8_t * read
where in the buffer reads are taken from
Definition buf.h:33
static void fr_bio_buf_write_undo(fr_bio_buf_t *bio_buf, size_t size)
Definition buf.h:111
static int fr_bio_buf_write_alloc(fr_bio_buf_t *bio_buf, size_t size)
Definition buf.h:98
uint8_t * write
where in the buffer writes are sent to
Definition buf.h:34
int fr_bio_buf_alloc(TALLOC_CTX *ctx, fr_bio_buf_t *bio_buf, size_t size)
Definition buf.c:114
ssize_t fr_bio_buf_write(fr_bio_buf_t *bio_buf, const void *buffer, size_t size)
Definition buf.c:81
static size_t fr_bio_buf_size(fr_bio_buf_t const *bio_buf)
Definition buf.h:151
#define RCSIDH(h, id)
Definition build.h:484
long int ssize_t
unsigned char uint8_t
#define fr_assert(_expr)
Definition rad_assert.h:38
int nonnull(2, 5))