a85b5759f3
These files were pulled from the 1.6.3 release tarball. This new version builds against OpenSSL version 1.1 which will be the default in the new Debian Stable which is due to be released RealSoonNow (tm).
192 lines
4.0 KiB
C
192 lines
4.0 KiB
C
/*
|
|
* buffer.c -- generic memory buffer .
|
|
*
|
|
* Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
|
|
*
|
|
* See LICENSE for the license.
|
|
*
|
|
*/
|
|
/**
|
|
* \file
|
|
*
|
|
* This file contains the definition of sldns_buffer, and functions to manipulate those.
|
|
*/
|
|
#include "config.h"
|
|
#include "sldns/sbuffer.h"
|
|
#include <stdarg.h>
|
|
|
|
sldns_buffer *
|
|
sldns_buffer_new(size_t capacity)
|
|
{
|
|
sldns_buffer *buffer = (sldns_buffer*)malloc(sizeof(sldns_buffer));
|
|
|
|
if (!buffer) {
|
|
return NULL;
|
|
}
|
|
|
|
buffer->_data = (uint8_t *) malloc(capacity);
|
|
if (!buffer->_data) {
|
|
free(buffer);
|
|
return NULL;
|
|
}
|
|
|
|
buffer->_position = 0;
|
|
buffer->_limit = buffer->_capacity = capacity;
|
|
buffer->_fixed = 0;
|
|
buffer->_vfixed = 0;
|
|
buffer->_status_err = 0;
|
|
|
|
sldns_buffer_invariant(buffer);
|
|
|
|
return buffer;
|
|
}
|
|
|
|
void
|
|
sldns_buffer_new_frm_data(sldns_buffer *buffer, void *data, size_t size)
|
|
{
|
|
assert(data != NULL);
|
|
|
|
buffer->_position = 0;
|
|
buffer->_limit = buffer->_capacity = size;
|
|
buffer->_fixed = 0;
|
|
buffer->_vfixed = 0;
|
|
buffer->_data = malloc(size);
|
|
if(!buffer->_data) {
|
|
buffer->_status_err = 1;
|
|
return;
|
|
}
|
|
memcpy(buffer->_data, data, size);
|
|
buffer->_status_err = 0;
|
|
|
|
sldns_buffer_invariant(buffer);
|
|
}
|
|
|
|
void
|
|
sldns_buffer_init_frm_data(sldns_buffer *buffer, void *data, size_t size)
|
|
{
|
|
memset(buffer, 0, sizeof(*buffer));
|
|
buffer->_data = data;
|
|
buffer->_capacity = buffer->_limit = size;
|
|
buffer->_fixed = 1;
|
|
buffer->_vfixed = 0;
|
|
}
|
|
|
|
void
|
|
sldns_buffer_init_vfixed_frm_data(sldns_buffer *buffer, void *data, size_t size)
|
|
{
|
|
memset(buffer, 0, sizeof(*buffer));
|
|
buffer->_data = data;
|
|
buffer->_capacity = buffer->_limit = size;
|
|
buffer->_fixed = 1;
|
|
buffer->_vfixed = 1;
|
|
}
|
|
|
|
int
|
|
sldns_buffer_set_capacity(sldns_buffer *buffer, size_t capacity)
|
|
{
|
|
void *data;
|
|
|
|
sldns_buffer_invariant(buffer);
|
|
assert(buffer->_position <= capacity && !buffer->_fixed);
|
|
|
|
data = (uint8_t *) realloc(buffer->_data, capacity);
|
|
if (!data) {
|
|
buffer->_status_err = 1;
|
|
return 0;
|
|
} else {
|
|
buffer->_data = data;
|
|
buffer->_limit = buffer->_capacity = capacity;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int
|
|
sldns_buffer_reserve(sldns_buffer *buffer, size_t amount)
|
|
{
|
|
sldns_buffer_invariant(buffer);
|
|
assert(!buffer->_fixed);
|
|
if (buffer->_capacity < buffer->_position + amount) {
|
|
size_t new_capacity = buffer->_capacity * 3 / 2;
|
|
|
|
if (new_capacity < buffer->_position + amount) {
|
|
new_capacity = buffer->_position + amount;
|
|
}
|
|
if (!sldns_buffer_set_capacity(buffer, new_capacity)) {
|
|
buffer->_status_err = 1;
|
|
return 0;
|
|
}
|
|
}
|
|
buffer->_limit = buffer->_capacity;
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
sldns_buffer_printf(sldns_buffer *buffer, const char *format, ...)
|
|
{
|
|
va_list args;
|
|
int written = 0;
|
|
size_t remaining;
|
|
|
|
if (sldns_buffer_status_ok(buffer)) {
|
|
sldns_buffer_invariant(buffer);
|
|
assert(buffer->_limit == buffer->_capacity);
|
|
|
|
remaining = sldns_buffer_remaining(buffer);
|
|
va_start(args, format);
|
|
written = vsnprintf((char *) sldns_buffer_current(buffer), remaining,
|
|
format, args);
|
|
va_end(args);
|
|
if (written == -1) {
|
|
buffer->_status_err = 1;
|
|
return -1;
|
|
} else if (!buffer->_vfixed && (size_t) written >= remaining) {
|
|
if (!sldns_buffer_reserve(buffer, (size_t) written + 1)) {
|
|
buffer->_status_err = 1;
|
|
return -1;
|
|
}
|
|
va_start(args, format);
|
|
written = vsnprintf((char *) sldns_buffer_current(buffer),
|
|
sldns_buffer_remaining(buffer), format, args);
|
|
va_end(args);
|
|
if (written == -1) {
|
|
buffer->_status_err = 1;
|
|
return -1;
|
|
}
|
|
}
|
|
buffer->_position += written;
|
|
}
|
|
return written;
|
|
}
|
|
|
|
void
|
|
sldns_buffer_free(sldns_buffer *buffer)
|
|
{
|
|
if (!buffer) {
|
|
return;
|
|
}
|
|
|
|
if (!buffer->_fixed)
|
|
free(buffer->_data);
|
|
|
|
free(buffer);
|
|
}
|
|
|
|
void *
|
|
sldns_buffer_export(sldns_buffer *buffer)
|
|
{
|
|
buffer->_fixed = 1;
|
|
return buffer->_data;
|
|
}
|
|
|
|
void
|
|
sldns_buffer_copy(sldns_buffer* result, sldns_buffer* from)
|
|
{
|
|
size_t tocopy = sldns_buffer_limit(from);
|
|
|
|
if(tocopy > sldns_buffer_capacity(result))
|
|
tocopy = sldns_buffer_capacity(result);
|
|
sldns_buffer_clear(result);
|
|
sldns_buffer_write(result, sldns_buffer_begin(from), tocopy);
|
|
sldns_buffer_flip(result);
|
|
}
|