#include <stdlib.h>
#include <string.h>
-static int
-grow_realloc(struct nettle_buffer *buffer,
- unsigned length)
+int
+nettle_buffer_grow(struct nettle_buffer *buffer,
+ unsigned length)
{
- if (!length)
- {
- realloc(buffer->contents, 0);
- buffer->contents = NULL;
- buffer->alloc = 0;
- buffer->size = 0;
-
- return 1;
- }
- else
+ assert(buffer->size <= buffer->realloc);
+
+ if (buffer->size + length > buffer->alloc)
{
- unsigned alloc = buffer->alloc * 2 + length + 100;
- uint8_t *p = realloc(buffer->contents, alloc);
+ unsigned alloc;
+ uint8_t *p;
+
+ if (!buffer->realloc)
+ return 0;
+
+ alloc = buffer->alloc * 2 + length + 100;
+ p = buffer->realloc(buffer->realloc_ctx, buffer->contents, alloc);
if (!p)
return 0;
buffer->contents = p;
buffer->alloc = alloc;
-
- return 1;
}
-}
-
-void
-nettle_buffer_init(struct nettle_buffer *buffer)
-{
- buffer->contents = NULL;
- buffer->alloc = 0;
- buffer->grow = grow_realloc;
- buffer->size = 0;
+ return 1;
}
void
{
buffer->contents = space;
buffer->alloc = length;
- buffer->grow = NULL;
+ buffer->realloc = NULL;
+ buffer->realloc_ctx = NULL;
buffer->size = 0;
}
void
nettle_buffer_clear(struct nettle_buffer *buffer)
{
- NETTLE_BUFFER_GROW(buffer, 0);
+ if (buffer->realloc)
+ buffer->realloc(buffer->realloc_ctx, buffer->contents, 0);
+
+ buffer->contents = NULL;
+ buffer->alloc = 0;
+ buffer->size = 0;
}
uint8_t *
unsigned length)
{
uint8_t *p;
- if (buffer->size + length > buffer->alloc)
- if (!NETTLE_BUFFER_GROW(buffer, length))
- return NULL;
+
+ if (!nettle_buffer_grow(buffer, length))
+ return NULL;
p = buffer->contents + buffer->size;
buffer->size += length;
#ifndef NETTLE_BUFFER_H_INCLUDED
#define NETTLE_BUFFER_H_INCLUDED
-#include <inttypes.h>
+#include "realloc.h"
struct nettle_buffer
{
uint8_t *contents;
/* Allocated size */
unsigned alloc;
-
- /* If GROW is NULL, no reallocation is done. Otherwise, it should be
- * a function that reallocates the contents to at least the size SIZE
- * + LENGTH. It can return 0 if allocation fails. Furthermore, if
- * GROW is called with LENGTH = 0, it should deallocate the buffer
- * space. */
- int (*grow)(struct nettle_buffer *buffer, unsigned length);
+
+ nettle_realloc_func *realloc;
+ void *realloc_ctx;
/* Current size */
unsigned size;
void
nettle_buffer_clear(struct nettle_buffer *buffer);
-/* FIXME: Put the comparison buffer->size + length > buffer->alloc
- * inside this macro. */
-#define NETTLE_BUFFER_GROW(o, l) ((o)->grow && (o)->grow((o), l))
+int
+nettle_buffer_grow(struct nettle_buffer *buffer,
+ unsigned length);
#define NETTLE_BUFFER_PUTC(buffer, c) \
-( (((buffer)->size < (buffer)->alloc) || NETTLE_BUFFER_GROW((buffer), 1)) \
+( (((buffer)->size < (buffer)->alloc) || nettle_buffer_grow((buffer), 1)) \
&& ((buffer)->contents[(buffer)->size++] = (c), 1) )
int