GNUnet  0.11.x
buffer.c
Go to the documentation of this file.
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 */
21 #include "platform.h"
22 #include "gnunet_util_lib.h"
23 #include "gnunet_buffer_lib.h"
24 
34 void
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 
54 void
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 */
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 
85 void
87  const char *data,
88  size_t len)
89 {
91  memcpy (buf->mem + buf->position, data, len);
92  buf->position += len;
93 }
94 
95 
102 void
104  const char *str)
105 {
106  size_t len = strlen (str);
107 
108  GNUNET_buffer_write (buf, str, len);
109 }
110 
111 
122 char *
124 {
125  char *res;
126 
127  /* ensure 0-termination */
128  if ( (0 == buf->position) || ('\0' != buf->mem[buf->position - 1]))
129  {
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 
148 void *
150 {
151  *size = buf->position;
152  void *res = buf->mem;
153  memset (buf, 0, sizeof (struct GNUNET_Buffer));
154  return res;
155 }
156 
157 
163 void
165 {
166  GNUNET_free (buf->mem);
167  memset (buf, 0, sizeof (struct GNUNET_Buffer));
168 }
169 
170 
179 void
180 GNUNET_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  {
192  buf->mem[buf->position++] = '/';
193  }
194  GNUNET_buffer_write (buf, str, len);
195 }
196 
197 
208 void
209 GNUNET_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 
229 void
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 
263 void
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;
274  outlen);
275  GNUNET_assert (NULL !=
277  data_len,
278  (buf->mem
279  + buf->position),
280  outlen));
281  buf->position += outlen;
282  GNUNET_assert (buf->position <= buf->capacity);
283 }
size_t capacity
Capacity of the buffer.
char * GNUNET_buffer_reap_str(struct GNUNET_Buffer *buf)
Clear the buffer and return the string it contained.
Definition: buffer.c:123
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void * GNUNET_buffer_reap(struct GNUNET_Buffer *buf, size_t *size)
Clear the buffer and return its contents.
Definition: buffer.c:149
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_buffer_write(struct GNUNET_Buffer *buf, const char *data, size_t len)
Write bytes to the buffer.
Definition: buffer.c:86
void GNUNET_buffer_write_str(struct GNUNET_Buffer *buf, const char *str)
Write a 0-terminated string to a buffer, excluding the 0-terminator.
Definition: buffer.c:103
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
void GNUNET_buffer_write_fstr(struct GNUNET_Buffer *buf, const char *fmt,...)
Write a 0-terminated formatted string to a buffer, excluding the 0-terminator.
Definition: buffer.c:209
static char buf[2048]
void GNUNET_buffer_clear(struct GNUNET_Buffer *buf)
Free the backing memory of the given buffer.
Definition: buffer.c:164
char * mem
Backing memory.
size_t position
Current write position.
static int res
static unsigned int size
Size of the "table".
Definition: peer.c:67
void GNUNET_buffer_write_data_encoded(struct GNUNET_Buffer *buf, const void *data, size_t data_len)
Write data encoded via GNUNET_STRINGS_data_to_string to the buffer.
Definition: buffer.c:264
void GNUNET_buffer_write_vfstr(struct GNUNET_Buffer *buf, const char *fmt, va_list args)
Write a 0-terminated formatted string to a buffer, excluding the 0-terminator.
Definition: buffer.c:230
void GNUNET_buffer_prealloc(struct GNUNET_Buffer *buf, size_t capacity)
Initialize a buffer with the given capacity.
Definition: buffer.c:35
void GNUNET_buffer_ensure_remaining(struct GNUNET_Buffer *buf, size_t n)
Make sure that at least n bytes remaining in the buffer.
Definition: buffer.c:55
void GNUNET_buffer_write_path(struct GNUNET_Buffer *buf, const char *str)
Write a path component to a buffer, ensuring that there is exactly one slash between the previous con...
Definition: buffer.c:180
Common buffer management functions.
uint32_t data
The data value.
int warn_grow
Log a warning if the buffer is grown over its initially allocated capacity.
#define GNUNET_malloc(size)
Wrapper around malloc.
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:871
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...