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