1/*********************************************************************** 2* 3* l2tp/handlers/dstring.c 4* 5* Implements simple buffer which grows to accomodate accumulated string 6* data 7* 8* Copyright (C) 2002 by Roaring Penguin Software Inc. 9* 10* This software may be distributed under the terms of the GNU General 11* Public License, Version 2, or (at your option) any later version. 12* 13* LIC: GPL 14* 15***********************************************************************/ 16 17static char const RCSID[] = 18"$Id: dstring.c 3323 2011-09-21 18:45:48Z lly.dev $"; 19 20#define INITIAL_SIZE 128 21#define GROW_FACTOR 2 22 23#include "dstring.h" 24#include <stdlib.h> 25#include <string.h> 26 27static int 28expand_for_size(dynstring *str, size_t len) 29{ 30 size_t newlen; 31 32 if (len >= str->alloc_size * GROW_FACTOR) { 33 newlen = len + 1; 34 } else { 35 newlen = str->alloc_size * GROW_FACTOR; 36 } 37 38 str->data = realloc(str->data, newlen); 39 if (!str->data) { 40 str->alloc_size = 0; 41 str->actual_size = 0; 42 return -1; 43 } 44 45 str->alloc_size = newlen; 46 return 0; 47} 48 49/********************************************************************** 50* %FUNCTION: dynstring_init 51* %ARGUMENTS: 52* str -- a dynstring structure 53* %RETURNS: 54* 0 on success; -1 on failure 55* %DESCRIPTION: 56* Initializes dynamic string 57***********************************************************************/ 58int 59dynstring_init(dynstring *str) 60{ 61 str->data = malloc(INITIAL_SIZE); 62 if (!str->data) return -1; 63 64 str->alloc_size = INITIAL_SIZE; 65 str->actual_size = 0; 66 str->data[0] = 0; 67 return 0; 68} 69 70/********************************************************************** 71* %FUNCTION: dynstring_free 72* %ARGUMENTS: 73* str -- a dynstring structure 74* %RETURNS: 75* Nothing 76* %DESCRIPTION: 77* Frees resources used by dynamic string 78***********************************************************************/ 79void 80dynstring_free(dynstring *str) 81{ 82 if (str->data) { 83 free(str->data); 84 str->data = NULL; 85 } 86 str->alloc_size = 0; 87 str->actual_size = 0; 88} 89 90/********************************************************************** 91* %FUNCTION: dynstring_append 92* %ARGUMENTS: 93* str -- dynamic string 94* s2 -- string to append 95* %RETURNS: 96* -1 on failure; 0 on success 97* %DESCRIPTION: 98* Appends s2 to str 99***********************************************************************/ 100int 101dynstring_append(dynstring *str, char const *s2) 102{ 103 return dynstring_append_len(str, s2, strlen(s2)); 104} 105 106/********************************************************************** 107* %FUNCTION: dynstring_append_len 108* %ARGUMENTS: 109* str -- dynamic string 110* s2 -- string to append 111* len -- length of s2 112* %RETURNS: 113* -1 on failure; 0 on success 114* %DESCRIPTION: 115* Appends s2 to str 116***********************************************************************/ 117int 118dynstring_append_len(dynstring *str, char const *s2, size_t len) 119{ 120 if (!len) return 0; 121 if (!str->data) return -1; 122 123 if (len + str->actual_size >= str->alloc_size) { 124 if (expand_for_size(str, str->actual_size + len) < 0) { 125 return -1; 126 } 127 } 128 129 memcpy(str->data + str->actual_size, s2, len); 130 str->actual_size += len; 131 str->data[str->actual_size] = 0; 132 return 0; 133} 134 135char const * 136dynstring_data(dynstring *str) 137{ 138 return str->data; 139} 140