Files
wget2/libwget/buffer.c
Tim Rühsen c6ee3d79ad Fix syntax-check 'sc_prohibit_have_config_h'
* cfg.mk: Remove sc_prohibit_have_config_h from local-checks-to-skip
* libwget/*.c: Include <config.h> unconditionally
* src/*.c: Likewise
* tests/*.c: Likewise
2017-04-30 22:01:34 +02:00

228 lines
5.0 KiB
C

/*
* Copyright(c) 2012 Tim Ruehsen
* Copyright(c) 2015-2016 Free Software Foundation, Inc.
*
* This file is part of libwget.
*
* Libwget is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Libwget is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libwget. If not, see <https://www.gnu.org/licenses/>.
*
*
* Memory buffer data structure routines
*
* Changelog
* 22.08.2012 Tim Ruehsen created
*
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <wget.h>
#include "private.h"
//#define ALIGNMENT 16
//#define PADDING(n) ((n) + (ALIGNMENT - (n)%ALIGNMENT))
wget_buffer_t *wget_buffer_init(wget_buffer_t *buf, char *data, size_t size)
{
if (!buf) {
buf = xmalloc(sizeof(wget_buffer_t));
buf->release_buf = 1;
} else
buf->release_buf = 0;
if (data && likely(size)) {
buf->size = size - 1;
buf->data = data;
*buf->data = 0; // always 0 terminate data to allow string functions
buf->release_data = 0;
} else {
if (!size)
size = 128;
buf->size = size;
buf->data = xmalloc(size + 1);
*buf->data = 0; // always 0 terminate data to allow string functions
buf->release_data = 1;
}
buf->length = 0;
return buf;
}
wget_buffer_t *wget_buffer_alloc(size_t size)
{
return wget_buffer_init(NULL, NULL, size);
}
void wget_buffer_realloc(wget_buffer_t *buf, size_t size)
{
const char *old_data = buf->data;
buf->size = size;
// buf->size = buf->size ? (size / buf->size + 1) * buf->size : size;
buf->data = xmalloc(buf->size + 1);
if (likely(old_data)) {
if (buf->length)
memcpy(buf->data, old_data, buf->length + 1);
else
*buf->data = 0; // always 0 terminate data to allow string functions
if (buf->release_data)
xfree(old_data);
} else
*buf->data = 0; // always 0 terminate data to allow string functions
buf->release_data = 1;
}
void wget_buffer_ensure_capacity(wget_buffer_t *buf, size_t size)
{
if (buf->size < size)
wget_buffer_realloc(buf, size);
}
void wget_buffer_deinit(wget_buffer_t *buf)
{
if (likely(buf)) {
if (buf->release_data) {
xfree(buf->data);
buf->release_data = 0;
}
if (buf->release_buf)
xfree(buf);
}
}
void wget_buffer_free(wget_buffer_t **buf)
{
if (likely(buf)) {
wget_buffer_deinit(*buf);
*buf = NULL;
}
}
void wget_buffer_free_data(wget_buffer_t *buf)
{
if (likely(buf)) {
if (buf->release_data) {
xfree(buf->data);
buf->release_data = 0;
buf->size = 0;
}
}
}
void wget_buffer_reset(wget_buffer_t *buf)
{
buf->length = 0;
*buf->data = 0;
}
size_t wget_buffer_memcpy(wget_buffer_t *buf, const void *data, size_t length)
{
buf->length = 0;
return wget_buffer_memcat(buf, data, length);
}
size_t wget_buffer_memcat(wget_buffer_t *buf, const void *data, size_t length)
{
if (length) {
if (buf->size < buf->length + length)
wget_buffer_realloc(buf, buf->size * 2 + length);
memcpy(buf->data + buf->length, data, length);
buf->length += length;
}
buf->data[buf->length] = 0; // always 0 terminate data to allow string functions
return buf->length;
}
size_t wget_buffer_strcpy(wget_buffer_t *buf, const char *s)
{
buf->length = 0;
return wget_buffer_memcat(buf, s, strlen(s));
}
size_t wget_buffer_strcat(wget_buffer_t *buf, const char *s)
{
return wget_buffer_memcat(buf, s, strlen(s));
}
size_t wget_buffer_bufcpy(wget_buffer_t *buf, wget_buffer_t *src)
{
return wget_buffer_memcpy(buf, src->data, src->length);
}
size_t wget_buffer_bufcat(wget_buffer_t *buf, wget_buffer_t *src)
{
return wget_buffer_memcat(buf, src->data, src->length);
}
size_t wget_buffer_memset(wget_buffer_t *buf, char c, size_t length)
{
buf->length = 0;
return wget_buffer_memset_append(buf, c, length);
}
size_t wget_buffer_memset_append(wget_buffer_t *buf, char c, size_t length)
{
if (likely(length)) {
if (unlikely(buf->size < buf->length + length))
wget_buffer_realloc(buf, buf->size * 2 + length);
memset(buf->data + buf->length, c, length);
buf->length += length;
}
buf->data[buf->length] = 0; // always 0 terminate data to allow string functions
return buf->length;
}
char *wget_buffer_trim(wget_buffer_t *buf)
{
if (buf->length) {
char *start = buf->data;
char *end = start + buf->length - 1;
if (isspace(*end)) {
// skip trailing spaces
for (; isspace(*end) && end >= start; end--)
;
end[1] = 0;
buf->length = (size_t) (end - start + 1);
}
if (isspace(*start)) {
// skip leading spaces
for (; isspace(*start) && end >= start; start++)
;
buf->length = (size_t) (end - start + 1);
memmove(buf->data, start, buf->length + 1); // include trailing 0
}
}
return buf->data;
}