1 #line 1 "../../../snprintfv/snprintfv/filament.in"
2 /* -*- Mode: C -*- */
3
4 /* filament.h --- a bit like a string but different =)O|
5 * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan
6 * Originally by Gary V. Vaughan, 1998
7 * This file is part of Snprintfv
8 *
9 * Snprintfv is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * Snprintfv program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 *
23 * As a special exception to the GNU General Public License, if you
24 * distribute this file as part of a program that also links with and
25 * uses the libopts library from AutoGen, you may include it under
26 * the same distribution terms used by the libopts library.
27 */
28
29 /* Code: */
30
31 #ifndef FILAMENT_H
32 #define FILAMENT_H 1
33
34 #include <snprintfv/compat.h>
35
36 #ifdef __cplusplus
37 extern "C"
38 {
39 #if 0
40 /* This brace is so that emacs can still indent properly: */ }
41 #endif
42 #endif /* __cplusplus */
43
44 #define FILAMENT_BUFSIZ 512
45
46 /**
47 * Filament:
48 * Opaque data type used to hold 8-bit clean dynamic strings which know
49 * their own length and resize themselves to avoid buffer overruns.
50 **/
51 typedef struct filament Filament;
52
53 struct filament
54 {
55 char *value; /* pointer to the start of the string */
56 size_t length; /* length of the string */
57 size_t size; /* total memory allocated */
58 char buffer[FILAMENT_BUFSIZ]; /* usually string == &buffer[0] */
59 };
60
61 /**
62 * filnew: constructor
63 * @init: address of the first byte to copy into the new object.
64 * @len: the number of bytes to copy into the new object.
65 *
66 * Create a new Filament object, initialised to hold a copy of the
67 * first @len bytes starting at address @init. If @init is NULL, or
68 * @len is 0 (or less), then the initialised Filament will return the
69 * empty string, "", if its value is queried.
70 *
71 * Return value:
72 * A newly created Filament object is returned.
73 **/
74 extern Filament * filnew (const char *const init, size_t len);
75
76
77 /**
78 * filinit:
79 * @fil: The Filament object to initialise.
80 * @init: address of the first byte to copy into the new object.
81 * @len: the number of bytes to copy into the new object.
82 *
83 * Initialise a Filament object to hold a copy of the first @len bytes
84 * starting at address @init. If @init is NULL, or @len is 0 (or less),
85 * then the Filament will be reset to hold the empty string, "".
86 *
87 * Return value:
88 * The initialised Filament object is returned.
89 **/
90 extern Filament * filinit (Filament *fil, const char *const init, size_t len);
91
92
93 /**
94 * fildelete: destructor
95 * @fil: The Filament object for recycling.
96 *
97 * The memory being used by @fil is recycled.
98 *
99 * Return value:
100 * The original contents of @fil are converted to a null terminated
101 * string which is returned, either to be freed itself or else used
102 * as a normal C string. The entire Filament contents are copied into
103 * this string including any embedded nulls.
104 **/
105 extern char * fildelete (Filament *fil);
106
107
108 /**
109 * _fil_extend:
110 * @fil: The Filament object which may need more string space.
111 * @len: The length of the data to be stored in @fil.
112 * @copy: whether to copy data from the static buffer on reallocation.
113 *
114 * This function will will assign a bigger block of memory to @fil
115 * considering the space left in @fil and @len, the length required
116 * for the prospective contents.
117 */
118 extern void _fil_extend (Filament *fil, size_t len, boolean copy);
119
120
121 #line 61 "../../../snprintfv/snprintfv/filament.in"
122
123 /* Save the overhead of a function call in the great majority of cases. */
124 #define fil_maybe_extend(fil, len, copy) \
125 (((len)>=(fil)->size) ? _fil_extend((fil), (len), (copy)) : (void)0)
126
127 /**
128 * filval:
129 * @fil: The Filament object being queried.
130 *
131 * Return value:
132 * A pointer to the null terminated string held by the Filament
133 * object is returned. Since the @fil may contain embedded nulls, it
134 * is not entirely safe to use the strfoo() API to examine the contents
135 * of the return value.
136 **/
137 SNV_INLINE char *
filval(Filament * fil)138 filval (Filament *fil)
139 {
140 /* Because we have been careful to ensure there is always at least
141 one spare byte of allocated memory, it is safe to set it here. */
142 fil->value[fil->length] = '\0';
143 return (char *) (fil->value);
144 }
145
146 /**
147 * fillen:
148 * @fil: The Filament object being queried.
149 *
150 * Return value:
151 * The length of @fil, including any embedded nulls, but excluding the
152 * terminating null, is returned.
153 **/
154 SNV_INLINE size_t
fillen(Filament * fil)155 fillen (Filament *fil)
156 {
157 return fil->length;
158 }
159
160 /**
161 * filelt:
162 * @fil: The Filament being queried.
163 * @n: A zero based index into @fil.
164 *
165 * This function looks for the @n'th element of @fil.
166 *
167 * Return value:
168 * If @n is an index inside the Filament @fil, then the character stored
169 * at that index cast to an int is returned, otherwise @n is outside
170 * this range and -1 is returned.
171 **/
172 SNV_INLINE int
filelt(Filament * fil,ssize_t n)173 filelt (Filament *fil, ssize_t n)
174 {
175 if ((n >= 0) && (n < fil->length))
176 return (int) fil->value[n];
177 else
178 return -1;
179 }
180
181 /**
182 * filncat:
183 * @fil: The destination Filament of the concatenation.
184 * @str: The address of the source bytes for concatenation.
185 * @n: The number of bytes to be copied from @str.
186 *
187 * @n bytes starting with the byte at address @str are destructively
188 * concatenated to @fil. If necessary, @fil is dynamically reallocated
189 * to make room for this operation.
190 *
191 * Return value:
192 * A pointer to the (not null terminated) string which is the result
193 * of this concatenation is returned.
194 **/
195 SNV_INLINE char *
filncat(Filament * fil,const char * str,size_t n)196 filncat (Filament *fil, const char *str, size_t n)
197 {
198 fil_maybe_extend (fil, n + fil->length, TRUE);
199 memcpy (fil->value + fil->length, str, n);
200 fil->length += n;
201 return fil->value;
202 }
203
204 /**
205 * filcat:
206 * @fil: The destination Filament of the concatenation.
207 * @str: The address of the source bytes for concatenation.
208 *
209 * The bytes starting at address @str upto and including the first null
210 * byte encountered are destructively concatenated to @fil. If
211 * necessary @fil is dynamically reallocated to make room for this
212 * operation.
213 *
214 * Return value:
215 * A pointer to the (not null terminated) string which is the result
216 * of this concatenation is returned.
217 **/
218 SNV_INLINE char *
filcat(Filament * fil,const char * str)219 filcat (Filament *fil, const char *str)
220 {
221 size_t length = strlen (str);
222 return filncat (fil, str, length);
223 }
224
225 /**
226 * filccat:
227 * @fil: The destination Filament of the concatenation.
228 * @c: The character to append to @fil.
229 *
230 * @c is destructively concatenated to @fil. If necessary, @fil is
231 * dynamically reallocated to make room for this operation. When used
232 * repeatedly this function is less efficient than %filncat,
233 * since it must check whether to extend the filament before each
234 * character is appended.
235 *
236 * Return value:
237 * A pointer to the (not null terminated) string which is the result
238 * of this concatenation is returned.
239 **/
240 SNV_INLINE char *
filccat(Filament * fil,int c)241 filccat (Filament *fil, int c)
242 {
243 fil_maybe_extend (fil, 1 + fil->length, TRUE);
244 fil->value[fil->length++] = c;
245 return fil->value;
246 }
247
248 #ifdef __cplusplus
249 #if 0
250 /* This brace is so that emacs can still indent properly: */
251 {
252 #endif
253 }
254 #endif /* __cplusplus */
255
256 #endif /* FILAMENT_H */
257
258 /* filament.h ends here */
259