Browse Source

Add the string_buffer module

master
Damien Goutte-Gattat 9 years ago
parent
commit
f277ddc79e
3 changed files with 301 additions and 1 deletions
  1. +2
    -1
      lib/Makefile.am
  2. +231
    -0
      lib/sbuffer.c
  3. +68
    -0
      lib/sbuffer.h

+ 2
- 1
lib/Makefile.am View File

@ -1,6 +1,7 @@
noinst_LIBRARIES = libfmail.a
libfmail_a_SOURCES = err.compat.h compat.h xmem.c xmem.h
libfmail_a_SOURCES = err.compat.h compat.h xmem.c xmem.h \
sbuffer.c sbuffer.h
libfmail_a_LIBADD = $(LIBOBJS)


+ 231
- 0
lib/sbuffer.c View File

@ -0,0 +1,231 @@
/*
* sbuffer - Incenp.org Notch Library: string buffer module
* Copyright (C) 2011 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sbuffer.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef EXIT_ON_ENOMEM
#include <xmem.h>
#endif
struct string_buffer_t
{
char *buffer;
size_t len;
size_t size;
size_t block;
};
#define AVAILABLE_SIZE(s) ((s)->size - (s)->len)
#define CURSOR(s) ((s)->buffer + (s)->len)
#ifdef EXIT_ON_NOMEM
#define GROW(s,l) \
do { \
(s)->size = ((((s)->len + (l)) / (s)->block) + 1) * (s)->block; \
(s)->buffer = xrealloc((s)->buffer, (s)->len); \
} while ( 0 )
#else
#define GROW(s,l) \
do { \
size_t ns = ((((s)->len + (l)) / (s)->block) + 1) * (s)->block; \
char *np = realloc((s)->buffer, ns); \
if ( ! np ) \
return -1; \
(s)->buffer = np; \
(s)->size = ns; \
} while ( 0 )
#endif
string_buffer_t *
sb_new(size_t block_size)
{
string_buffer_t *s;
if ( ! block_size )
block_size = 128;
#ifdef EXIT_ON_ENOMEM
s = xmalloc(sizeof(*s));
s->block = s->size = block_size;
s->buffer = xmalloc(block_size);
sb_empty(s);
#else
if ( (s = malloc(sizeof(*s))) ) {
s->block = s->size = block_size;
if ( (s->buffer = malloc(block_size)) )
sb_empty(s);
else {
free(s);
s = NULL;
}
}
#endif
return s;
}
void
sb_free(string_buffer_t *s)
{
if ( s ) {
free(s->buffer);
free(s);
}
}
const char *
sb_get(string_buffer_t *s)
{
return s ? s->buffer : NULL;
}
char *
sb_get_copy(string_buffer_t *s)
{
char *str = NULL;
if ( s ) {
#ifdef EXIT_ON_ENOMEM
str = xmalloc(s->len + 1);
#else
if ( ! (str = malloc(s->len + 1)) )
return NULL;
#endif
strncpy(str, s->buffer, s->len);
}
return str;
}
size_t
sb_len(string_buffer_t *s)
{
return s ? s->len : 0;
}
int
sb_empty(string_buffer_t *s)
{
if ( ! s ) {
errno = EINVAL;
return -1;
}
s->buffer[0] = '\0';
s->len = 0;
return 0;
}
int
sb_addc(string_buffer_t *s, char c)
{
if ( ! s ) {
errno = EINVAL;
return -1;
}
if ( AVAILABLE_SIZE(s) < 1 )
GROW(s, 1);
*(s->buffer + s->len++) = c;
*(s->buffer + s->len) = '\0';
return 0;
}
int
sb_add(string_buffer_t *s, const char *buffer)
{
if ( ! buffer ) {
errno = EINVAL;
return -1;
}
return sb_addn(s, buffer, strlen(buffer));
}
int
sb_addn(string_buffer_t *s, const char *buffer, size_t len)
{
if ( ! s || ! buffer ) {
errno = EINVAL;
return -1;
}
if ( AVAILABLE_SIZE(s) < len )
GROW(s, len);
strncat(CURSOR(s), buffer, len);
s->len += len;
return 0;
}
int
sb_vaddf(string_buffer_t *s, const char *fmt, va_list ap)
{
int written;
if ( ! s || ! fmt ) {
errno = EINVAL;
return -1;
}
written = vsnprintf(CURSOR(s), AVAILABLE_SIZE(s), fmt, ap);
if ( written >= AVAILABLE_SIZE(s) ) {
va_list aq;
GROW(s, written);
va_copy(aq, ap);
vsprintf(CURSOR(s), fmt, aq);
va_end(aq);
}
s->len += written;
return 0;
}
int
sb_addf(string_buffer_t *s, const char *fmt, ...)
{
int ret;
va_list ap;
if ( ! s || ! fmt ) {
errno = EINVAL;
return -1;
}
va_start(ap, fmt);
ret = sb_vaddf(s, fmt, ap);
va_end(ap);
return ret;
}

+ 68
- 0
lib/sbuffer.h View File

@ -0,0 +1,68 @@
/*
* sbuffer - Incenp.org Notch Library: string buffer module
* Copyright (C) 2011 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ICP20110203_SBUFFER_H
#define ICP20110203_SBUFFER_H
#include <stdlib.h>
#include <stdarg.h>
#ifdef __cpluscplus
extern "C" {
#endif
typedef struct string_buffer_t string_buffer_t;
string_buffer_t *
sb_new(size_t);
void
sb_free(string_buffer_t *);
const char *
sb_get(string_buffer_t *);
char *
sb_get_copy(string_buffer_t *);
size_t
sb_len(string_buffer_t *);
int
sb_empty(string_buffer_t *);
int
sb_addc(string_buffer_t *, char);
int
sb_add(string_buffer_t *, const char *);
int
sb_addn(string_buffer_t *, const char *, size_t);
int
sb_vaddf(string_buffer_t *, const char *, va_list);
int
sb_addf(string_buffer_t *, const char *, ...);
#ifdef __cplusplus
}
#endif
#endif /* !ICP20110203_SBUFFER_H */

Loading…
Cancel
Save