simplestring.c 6.9 KB

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