1 /*
2 This file is part of libXMLRPC - a C library for xml-encoded function calls.
3
4 Author: Dan Libby (dan@libby.com)
5 Epinions.com may be contacted at feedback@epinions-inc.com
6 */
7
8 /*
9 Copyright 2000 Epinions, Inc.
10
11 Subject to the following 3 conditions, Epinions, Inc. permits you, free
12 of charge, to (a) use, copy, distribute, modify, perform and display this
13 software and associated documentation files (the "Software"), and (b)
14 permit others to whom the Software is furnished to do so as well.
15
16 1) The above copyright notice and this permission notice shall be included
17 without modification in all copies or substantial portions of the
18 Software.
19
20 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF
21 ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY
22 IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR
23 PURPOSE OR NONINFRINGEMENT.
24
25 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
26 SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
27 OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING
28 NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH
29 DAMAGES.
30
31 */
32
33
34 static const char rcsid[] = "#(@) $Id$";
35
36
37 #define SIMPLESTRING_INCR 32
38
39 /****h* ABOUT/simplestring
40 * NAME
41 * simplestring
42 * AUTHOR
43 * Dan Libby, aka danda (dan@libby.com)
44 * CREATION DATE
45 * 06/2000
46 * HISTORY
47 * $Log$
48 * Revision 1.3 2002/08/22 01:25:50 sniper
49 * kill some compile warnings
50 *
51 * Revision 1.2 2002/07/05 04:43:53 danda
52 * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51
53 *
54 * Revision 1.4 2002/02/13 20:58:50 danda
55 * patch to make source more windows friendly, contributed by Jeff Lawson
56 *
57 * Revision 1.3 2001/09/29 21:58:05 danda
58 * adding cvs log to history section
59 *
60 * 10/15/2000 -- danda -- adding robodoc documentation
61 * PORTABILITY
62 * Coded on RedHat Linux 6.2. Builds on Solaris x86. Should build on just
63 * about anything with minor mods.
64 * NOTES
65 * This code was written primarily for xmlrpc, but has found some other uses.
66 *
67 * simplestring is, as the name implies, a simple API for dealing with C strings.
68 * Why would I write yet another string API? Because I couldn't find any that were
69 * a) free / GPL, b) simple/lightweight, c) fast, not doing unnecessary strlens all
70 * over the place. So. It is simple, and it seems to work, and it is pretty fast.
71 *
72 * Oh, and it is also binary safe, ie it can handle strings with embedded NULLs,
73 * so long as the real length is passed in.
74 *
75 * And the masses rejoiced.
76 *
77 * BUGS
78 * there must be some.
79 ******/
80
81 #include <stdlib.h>
82 #include <string.h>
83 #include <limits.h>
84 #include "simplestring.h"
85
86 #define my_free(thing) if(thing) {free(thing); thing = 0;}
87
88 /*----------------------**
89 * Begin String Functions *
90 *-----------------------*/
91
92 /****f* FUNC/simplestring_init
93 * NAME
94 * simplestring_init
95 * SYNOPSIS
96 * void simplestring_init(simplestring* string)
97 * FUNCTION
98 * initialize string
99 * INPUTS
100 * string - pointer to a simplestring struct that will be initialized
101 * RESULT
102 * void
103 * NOTES
104 * SEE ALSO
105 * simplestring_free ()
106 * simplestring_clear ()
107 * SOURCE
108 */
simplestring_init(simplestring * string)109 void simplestring_init(simplestring* string) {
110 memset(string, 0, sizeof(simplestring));
111 }
112 /******/
113
simplestring_init_str(simplestring * string)114 static void simplestring_init_str(simplestring* string) {
115 string->str = (char*)malloc(SIMPLESTRING_INCR);
116 if(string->str) {
117 string->str[0] = 0;
118 string->len = 0;
119 string->size = SIMPLESTRING_INCR;
120 }
121 else {
122 string->size = 0;
123 }
124 }
125
126 /****f* FUNC/simplestring_clear
127 * NAME
128 * simplestring_clear
129 * SYNOPSIS
130 * void simplestring_clear(simplestring* string)
131 * FUNCTION
132 * clears contents of a string
133 * INPUTS
134 * string - the string value to clear
135 * RESULT
136 * void
137 * NOTES
138 * This function is very fast as it does not de-allocate any memory.
139 * SEE ALSO
140 *
141 * SOURCE
142 */
simplestring_clear(simplestring * string)143 void simplestring_clear(simplestring* string) {
144 if(string->str) {
145 string->str[0] = 0;
146 }
147 string->len = 0;
148 }
149 /******/
150
151 /****f* FUNC/simplestring_free
152 * NAME
153 * simplestring_free
154 * SYNOPSIS
155 * void simplestring_free(simplestring* string)
156 * FUNCTION
157 * frees contents of a string, if any. Does *not* free the simplestring struct itself.
158 * INPUTS
159 * string - value containing string to be free'd
160 * RESULT
161 * void
162 * NOTES
163 * caller is responsible for allocating and freeing simplestring* struct itself.
164 * SEE ALSO
165 * simplestring_init ()
166 * SOURCE
167 */
simplestring_free(simplestring * string)168 void simplestring_free(simplestring* string) {
169 if(string && string->str) {
170 my_free(string->str);
171 string->len = 0;
172 }
173 }
174 /******/
175
176 #ifndef SIZE_MAX
177 #define SIZE_MAX ((size_t)-1)
178 #endif
179 /****f* FUNC/simplestring_addn
180 * NAME
181 * simplestring_addn
182 * SYNOPSIS
183 * void simplestring_addn(simplestring* string, const char* add, int add_len)
184 * FUNCTION
185 * copies n characters from source to target string
186 * INPUTS
187 * target - target string
188 * source - source string
189 * add_len - number of characters to copy
190 * RESULT
191 * void
192 * NOTES
193 * SEE ALSO
194 * simplestring_add ()
195 * SOURCE
196 */
simplestring_addn(simplestring * target,const char * source,size_t add_len)197 void simplestring_addn(simplestring* target, const char* source, size_t add_len) {
198 size_t newsize = target->size, incr = 0;
199 if(target && source) {
200 if(!target->str) {
201 simplestring_init_str(target);
202 }
203
204 if((SIZE_MAX - add_len) < target->len || (SIZE_MAX - add_len - 1) < target->len) {
205 /* check for overflows, if there's a potential overflow do nothing */
206 return;
207 }
208
209 if(target->len + add_len + 1 > target->size) {
210 /* newsize is current length + new length */
211 newsize = target->len + add_len + 1;
212 incr = target->size * 2;
213
214 /* align to SIMPLESTRING_INCR increments */
215 if (incr) {
216 newsize = newsize - (newsize % incr) + incr;
217 }
218 if(newsize < (target->len + add_len + 1)) {
219 /* some kind of overflow happened */
220 return;
221 }
222 target->str = (char*)realloc(target->str, newsize);
223
224 target->size = target->str ? newsize : 0;
225 }
226
227 if(target->str) {
228 if(add_len) {
229 memcpy(target->str + target->len, source, add_len);
230 }
231 target->len += add_len;
232 target->str[target->len] = 0; /* null terminate */
233 }
234 }
235 }
236 /******/
237
238 /****f* FUNC/simplestring_add
239 * NAME
240 * simplestring_add
241 * SYNOPSIS
242 * void simplestring_add(simplestring* string, const char* add)
243 * FUNCTION
244 * appends a string of unknown length from source to target
245 * INPUTS
246 * target - the target string to append to
247 * source - the source string of unknown length
248 * RESULT
249 * void
250 * NOTES
251 * SEE ALSO
252 * simplestring_addn ()
253 * SOURCE
254 */
simplestring_add(simplestring * target,const char * source)255 void simplestring_add(simplestring* target, const char* source) {
256 if(target && source) {
257 simplestring_addn(target, source, strlen(source));
258 }
259 }
260 /******/
261
262
263 /*----------------------
264 * End String Functions *
265 *--------------------**/
266