The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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  */
27 RCSIDH(lib_bio_buf_h, "$Id: deae54c1bda80d1163fabb64e8db5e53373a10cb $")
28 
29 typedef 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
35 } fr_bio_buf_t;
36 
37 static 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 
43 size_t fr_bio_buf_make_room(fr_bio_buf_t *bio_buf);
44 
45 size_t fr_bio_buf_read(fr_bio_buf_t *bio_buf, void *buffer, size_t size) CC_HINT(nonnull(1));
46 ssize_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
50 static 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 
61 static 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 
68 static 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 
73 static 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 
82 static 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 
89 static 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 
98 static 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 
111 static 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 
125 static 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
131 static 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 
151 static 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 
158 int 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:574
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
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 uint8_t * fr_bio_buf_write_reserve(fr_bio_buf_t *bio_buf, size_t size)
Definition: buf.h:89
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:482
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
fr_assert(0)
int nonnull(2, 5))