aboutsummaryrefslogtreecommitdiff
path: root/src/util/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/buffer.c')
-rw-r--r--src/util/buffer.c283
1 files changed, 0 insertions, 283 deletions
diff --git a/src/util/buffer.c b/src/util/buffer.c
deleted file mode 100644
index 662e4d0f2..000000000
--- a/src/util/buffer.c
+++ /dev/null
@@ -1,283 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2020 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify it under the
6 terms of the GNU Affero General Public License as published by the Free Software
7 Foundation; either version 3, or (at your option) any later version.
8
9 GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
12
13 You should have received a copy of the GNU Affero General Public License along with
14 GNUnet; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15*/
16/**
17 * @file buffer.c
18 * @brief Common buffer management functions.
19 * @author Florian Dold
20 */
21#include "platform.h"
22#include "gnunet_util_lib.h"
23#include "gnunet_buffer_lib.h"
24
25/**
26 * Initialize a buffer with the given capacity.
27 *
28 * When a buffer is allocated with this function, a warning is logged
29 * when the buffer exceeds the initial capacity.
30 *
31 * @param buf the buffer to initialize
32 * @param capacity the capacity (in bytes) to allocate for @a buf
33 */
34void
35GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf,
36 size_t capacity)
37{
38 /* Buffer should be zero-initialized */
39 GNUNET_assert (0 == buf->mem);
40 GNUNET_assert (0 == buf->capacity);
41 GNUNET_assert (0 == buf->position);
42 buf->mem = GNUNET_malloc (capacity);
43 buf->capacity = capacity;
44 buf->warn_grow = GNUNET_YES;
45}
46
47
48/**
49 * Make sure that at least @a n bytes remaining in the buffer.
50 *
51 * @param buf buffer to potentially grow
52 * @param n number of bytes that should be available to write
53 */
54void
55GNUNET_buffer_ensure_remaining (struct GNUNET_Buffer *buf,
56 size_t n)
57{
58 size_t new_capacity = buf->position + n;
59
60 /* guard against overflow */
61 GNUNET_assert (new_capacity >= buf->position);
62 if (new_capacity <= buf->capacity)
63 return;
64 /* warn if calculation of expected size was wrong */
65 GNUNET_break (GNUNET_YES != buf->warn_grow);
66 if (new_capacity < buf->capacity * 2)
67 new_capacity = buf->capacity * 2;
68 buf->capacity = new_capacity;
69 if (NULL != buf->mem)
70 buf->mem = GNUNET_realloc (buf->mem, new_capacity);
71 else
72 buf->mem = GNUNET_malloc (new_capacity);
73}
74
75
76/**
77 * Write bytes to the buffer.
78 *
79 * Grows the buffer if necessary.
80 *
81 * @param buf buffer to write to
82 * @param data data to read from
83 * @param len number of bytes to copy from @a data to @a buf
84 */
85void
86GNUNET_buffer_write (struct GNUNET_Buffer *buf,
87 const char *data,
88 size_t len)
89{
90 GNUNET_buffer_ensure_remaining (buf, len);
91 memcpy (buf->mem + buf->position, data, len);
92 buf->position += len;
93}
94
95
96/**
97 * Write a 0-terminated string to a buffer, excluding the 0-terminator.
98 *
99 * @param buf the buffer to write to
100 * @param str the string to write to @a buf
101 */
102void
103GNUNET_buffer_write_str (struct GNUNET_Buffer *buf,
104 const char *str)
105{
106 size_t len = strlen (str);
107
108 GNUNET_buffer_write (buf, str, len);
109}
110
111
112/**
113 * Clear the buffer and return the string it contained.
114 * The caller is responsible to eventually #GNUNET_free
115 * the returned string.
116 *
117 * The returned string is always 0-terminated.
118 *
119 * @param buf the buffer to reap the string from
120 * @returns the buffer contained in the string
121 */
122char *
123GNUNET_buffer_reap_str (struct GNUNET_Buffer *buf)
124{
125 char *res;
126
127 /* ensure 0-termination */
128 if ( (0 == buf->position) || ('\0' != buf->mem[buf->position - 1]))
129 {
130 GNUNET_buffer_ensure_remaining (buf, 1);
131 buf->mem[buf->position++] = '\0';
132 }
133 res = buf->mem;
134 memset (buf, 0, sizeof (struct GNUNET_Buffer));
135 return res;
136}
137
138
139/**
140 * Clear the buffer and return its contents.
141 * The caller is responsible to eventually #GNUNET_free
142 * the returned data.
143 *
144 * @param buf the buffer to reap the contents from
145 * @param size where to store the size of the returned data
146 * @returns the data contained in the string
147 */
148void *
149GNUNET_buffer_reap (struct GNUNET_Buffer *buf, size_t *size)
150{
151 *size = buf->position;
152 void *res = buf->mem;
153 memset (buf, 0, sizeof (struct GNUNET_Buffer));
154 return res;
155}
156
157
158/**
159 * Free the backing memory of the given buffer.
160 * Does not free the memory of the buffer control structure,
161 * which is typically stack-allocated.
162 */
163void
164GNUNET_buffer_clear (struct GNUNET_Buffer *buf)
165{
166 GNUNET_free (buf->mem);
167 memset (buf, 0, sizeof (struct GNUNET_Buffer));
168}
169
170
171/**
172 * Write a path component to a buffer, ensuring that
173 * there is exactly one slash between the previous contents
174 * of the buffer and the new string.
175 *
176 * @param buf buffer to write to
177 * @param str string containing the new path component
178 */
179void
180GNUNET_buffer_write_path (struct GNUNET_Buffer *buf, const char *str)
181{
182 size_t len = strlen (str);
183
184 while ( (0 != len) && ('/' == str[0]) )
185 {
186 str++;
187 len--;
188 }
189 if ( (0 == buf->position) || ('/' != buf->mem[buf->position - 1]) )
190 {
191 GNUNET_buffer_ensure_remaining (buf, 1);
192 buf->mem[buf->position++] = '/';
193 }
194 GNUNET_buffer_write (buf, str, len);
195}
196
197
198/**
199 * Write a 0-terminated formatted string to a buffer, excluding the
200 * 0-terminator.
201 *
202 * Grows the buffer if necessary.
203 *
204 * @param buf the buffer to write to
205 * @param fmt format string
206 * @param ... format arguments
207 */
208void
209GNUNET_buffer_write_fstr (struct GNUNET_Buffer *buf, const char *fmt, ...)
210{
211 va_list args;
212
213 va_start (args, fmt);
214 GNUNET_buffer_write_vfstr (buf, fmt, args);
215 va_end (args);
216}
217
218
219/**
220 * Write a 0-terminated formatted string to a buffer, excluding the
221 * 0-terminator.
222 *
223 * Grows the buffer if necessary.
224 *
225 * @param buf the buffer to write to
226 * @param fmt format string
227 * @param args format argument list
228 */
229void
230GNUNET_buffer_write_vfstr (struct GNUNET_Buffer *buf,
231 const char *fmt,
232 va_list args)
233{
234 int res;
235 va_list args2;
236
237 va_copy (args2, args);
238 res = vsnprintf (NULL, 0, fmt, args2);
239 va_end (args2);
240
241 GNUNET_assert (res >= 0);
242 GNUNET_buffer_ensure_remaining (buf, res + 1);
243
244 va_copy (args2, args);
245 res = vsnprintf (buf->mem + buf->position, res + 1, fmt, args2);
246 va_end (args2);
247
248 GNUNET_assert (res >= 0);
249 buf->position += res;
250 GNUNET_assert (buf->position <= buf->capacity);
251}
252
253
254/**
255 * Write data encoded via #GNUNET_STRINGS_data_to_string to the buffer.
256 *
257 * Grows the buffer if necessary.
258 *
259 * @param buf buffer to write to
260 * @param data data to read from
261 * @param data_len number of bytes to copy from @a data to @a buf
262 */
263void
264GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf,
265 const void *data,
266 size_t data_len)
267{
268 size_t outlen = data_len * 8;
269
270 if (outlen % 5 > 0)
271 outlen += 5 - outlen % 5;
272 outlen /= 5;
273 GNUNET_buffer_ensure_remaining (buf,
274 outlen);
275 GNUNET_assert (NULL !=
276 GNUNET_STRINGS_data_to_string (data,
277 data_len,
278 (buf->mem
279 + buf->position),
280 outlen));
281 buf->position += outlen;
282 GNUNET_assert (buf->position <= buf->capacity);
283}