2
* This file is part of libESMTP, a library for submission of RFC 2822
3
* formatted electronic mail messages using the SMTP protocol described
6
* Copyright (C) 2001,2002 Brian Stafford <brian@stafford.uklinux.net>
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2.1 of the License, or (at your option) any later version.
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with this library; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
/* Stuff to maintain a dynamically sized buffer for a string. I seem
24
to keep writing code like this, so I've put it in a file by itself.
25
Maybe I should consolidate some other string buffering code with this.
27
NOTE: no \0 terminating strings
41
#include <missing.h> /* declarations for missing library functions */
43
#include "concatenate.h"
45
/* malloc/realloc the buffer to be the requested length.
46
Return 0 on failure, non-zero otherwise */
48
cat_alloc (struct catbuf *catbuf, size_t length)
52
assert (catbuf != NULL && length > 0);
54
if (catbuf->buffer == NULL)
55
catbuf->buffer = malloc (length);
58
nbuf = realloc (catbuf->buffer, length);
60
free (catbuf->buffer);
61
catbuf->buffer = nbuf;
63
catbuf->allocated = (catbuf->buffer == NULL) ? 0 : length;
64
if (catbuf->allocated < catbuf->string_length)
65
catbuf->string_length = catbuf->allocated;
66
return catbuf->buffer != NULL;
69
/* Reset the string to zero length without freeing the allocated memory */
71
cat_reset (struct catbuf *catbuf, size_t minimum_length)
73
assert (catbuf != NULL);
75
catbuf->string_length = 0;
76
if (minimum_length > catbuf->allocated)
77
cat_alloc (catbuf, minimum_length);
80
/* Initialise a buffer */
82
cat_init (struct catbuf *catbuf, size_t minimum_length)
84
assert (catbuf != NULL);
86
memset (catbuf, 0, sizeof (struct catbuf));
87
if (minimum_length > 0)
88
cat_alloc (catbuf, minimum_length);
91
/* Free memory allocated to the buffer */
93
cat_free (struct catbuf *catbuf)
95
assert (catbuf != NULL);
97
if (catbuf->buffer != NULL)
98
free (catbuf->buffer);
99
memset (catbuf, 0, sizeof (struct catbuf));
102
/* Return a pointer to the buffer and put its length in *len. */
104
cat_buffer (struct catbuf *catbuf, int *len)
106
assert (catbuf != NULL);
109
*len = catbuf->string_length;
110
return catbuf->buffer;
113
/* Shrink the allocated memory to the minimum needed. Return a
114
pointer to the buffer and put its length in *len. */
116
cat_shrink (struct catbuf *catbuf, int *len)
118
assert (catbuf != NULL);
120
if (catbuf->buffer != NULL)
121
cat_alloc (catbuf, catbuf->string_length);
123
*len = catbuf->string_length;
124
return catbuf->buffer;
127
/* Concatenate a string to the buffer. N.B. the buffer is NOT terminated
128
by a \0. If len < 0 then string must be \0 terminated. */
130
concatenate (struct catbuf *catbuf, const char *string, int len)
134
assert (catbuf != NULL && string != NULL);
137
len = strlen (string);
139
/* Ensure that the buffer is big enough to accept the string */
140
if (catbuf->buffer == NULL)
143
shortfall = len - (catbuf->allocated - catbuf->string_length);
146
if (shortfall % 128 != 0)
147
shortfall += 128 - shortfall % 128;
148
if (!cat_alloc (catbuf, catbuf->allocated + shortfall))
152
/* Copy the string */
153
memcpy (catbuf->buffer + catbuf->string_length, string, len);
154
catbuf->string_length += len;
156
return catbuf->buffer;
160
vconcatenate (struct catbuf *catbuf, ...)
165
assert (catbuf != NULL);
167
va_start (alist, catbuf);
168
while ((string = va_arg (alist, const char *)) != NULL)
169
concatenate (catbuf, string, -1);
171
return catbuf->buffer;
175
cat_printf (struct catbuf *catbuf, const char *format, ...)
181
assert (catbuf != NULL && format != NULL);
183
va_start (alist, format);
184
len = vsnprintf (buf, sizeof buf, format, alist);
188
if (len >= (int) sizeof buf)
190
concatenate (catbuf, buf, len);