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
35 GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf, size_t capacity)
36 {
37  /* Buffer should be zero-initialized */
38  GNUNET_assert (0 == buf->mem);
39  GNUNET_assert (0 == buf->capacity);
40  GNUNET_assert (0 == buf->position);
41  buf->mem = GNUNET_malloc (capacity);
42  buf->capacity = capacity;
43  buf->warn_grow = GNUNET_YES;
44 }
45 
46 
53 void
55 {
56  size_t new_capacity = buf->position + n;
57 
58  if (new_capacity <= buf->capacity)
59  return;
60  /* warn if calculation of expected size was wrong */
62  if (new_capacity < buf->capacity * 2)
63  new_capacity = buf->capacity * 2;
64  buf->capacity = new_capacity;
65  if (NULL != buf->mem)
66  buf->mem = GNUNET_realloc (buf->mem, new_capacity);
67  else
68  buf->mem = GNUNET_malloc (new_capacity);
69 }
70 
71 
82 void
83 GNUNET_buffer_write (struct GNUNET_Buffer *buf, const char *data, size_t len)
84 {
86  memcpy (buf->mem + buf->position, data, len);
87  buf->position += len;
88 }
89 
90 
97 void
98 GNUNET_buffer_write_str (struct GNUNET_Buffer *buf, const char *str)
99 {
100  size_t len = strlen (str);
101 
102  GNUNET_buffer_write (buf, str, len);
103 }
104 
105 
116 char *
118 {
119  char *res;
120 
121  /* ensure 0-termination */
122  if ( (0 == buf->position) || ('\0' != buf->mem[buf->position - 1]))
123  {
125  buf->mem[buf->position++] = '\0';
126  }
127  res = buf->mem;
128  *buf = (struct GNUNET_Buffer) { 0 };
129  return res;
130 }
131 
132 
138 void
140 {
141  GNUNET_free_non_null (buf->mem);
142  *buf = (struct GNUNET_Buffer) { 0 };
143 }
144 
145 
154 void
155 GNUNET_buffer_write_path (struct GNUNET_Buffer *buf, const char *str)
156 {
157  size_t len = strlen (str);
158 
159  while ( (0 != len) && ('/' == str[0]) )
160  {
161  str++;
162  len--;
163  }
164  if ( (0 == buf->position) || ('/' != buf->mem[buf->position - 1]) )
165  {
167  buf->mem[buf->position++] = '/';
168  }
169  GNUNET_buffer_write (buf, str, len);
170 }
171 
172 
183 void
184 GNUNET_buffer_write_fstr (struct GNUNET_Buffer *buf, const char *fmt, ...)
185 {
186  va_list args;
187 
188  va_start (args, fmt);
189  GNUNET_buffer_write_vfstr (buf, fmt, args);
190  va_end (args);
191 }
192 
193 
204 void
206  const char *fmt,
207  va_list args)
208 {
209  int res;
210  va_list args2;
211 
212  va_copy (args2, args);
213  res = vsnprintf (NULL, 0, fmt, args2);
214  va_end (args2);
215 
216  GNUNET_assert (res >= 0);
217  GNUNET_buffer_ensure_remaining (buf, res + 1);
218 
219  va_copy (args2, args);
220  res = vsnprintf (buf->mem + buf->position, res + 1, fmt, args2);
221  va_end (args2);
222 
223  GNUNET_assert (res >= 0);
224  buf->position += res;
225  GNUNET_assert (buf->position <= buf->capacity);
226 }
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:117
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#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:83
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:98
#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:184
static char buf[2048]
void GNUNET_buffer_clear(struct GNUNET_Buffer *buf)
Free the backing memory of the given buffer.
Definition: buffer.c:139
char * mem
Backing memory.
size_t position
Current write position.
static int res
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:205
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:54
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:155
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.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...