monero/external/unbound/sldns/sbuffer.c
Erik de Castro Lopo a85b5759f3 Upgrade unbound library
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).
2017-06-17 23:04:00 +10:00

191 lines
4 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);
}