simplestring.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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. #include <php.h>
  26. static const char rcsid[] = "#(@) $Id$";
  27. #define SIMPLESTRING_INCR 32
  28. /****h* ABOUT/simplestring
  29. * NAME
  30. * simplestring
  31. * AUTHOR
  32. * Dan Libby, aka danda (dan@libby.com)
  33. * CREATION DATE
  34. * 06/2000
  35. * HISTORY
  36. * $Log$
  37. * Revision 1.3 2002/08/22 01:25:50 sniper
  38. * kill some compile warnings
  39. *
  40. * Revision 1.2 2002/07/05 04:43:53 danda
  41. * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51
  42. *
  43. * Revision 1.4 2002/02/13 20:58:50 danda
  44. * patch to make source more windows friendly, contributed by Jeff Lawson
  45. *
  46. * Revision 1.3 2001/09/29 21:58:05 danda
  47. * adding cvs log to history section
  48. *
  49. * 10/15/2000 -- danda -- adding robodoc documentation
  50. * PORTABILITY
  51. * Coded on RedHat Linux 6.2. Builds on Solaris x86. Should build on just
  52. * about anything with minor mods.
  53. * NOTES
  54. * This code was written primarily for xmlrpc, but has found some other uses.
  55. *
  56. * simplestring is, as the name implies, a simple API for dealing with C strings.
  57. * Why would I write yet another string API? Because I couldn't find any that were
  58. * a) free / GPL, b) simple/lightweight, c) fast, not doing unnecessary strlens all
  59. * over the place. So. It is simple, and it seems to work, and it is pretty fast.
  60. *
  61. * Oh, and it is also binary safe, ie it can handle strings with embedded NULLs,
  62. * so long as the real length is passed in.
  63. *
  64. * And the masses rejoiced.
  65. *
  66. * BUGS
  67. * there must be some.
  68. ******/
  69. #include <stdlib.h>
  70. #include <string.h>
  71. #include <limits.h>
  72. #include "simplestring.h"
  73. #define my_free(thing) if(thing) {efree(thing); thing = 0;}
  74. /*----------------------**
  75. * Begin String Functions *
  76. *-----------------------*/
  77. /****f* FUNC/simplestring_init
  78. * NAME
  79. * simplestring_init
  80. * SYNOPSIS
  81. * void simplestring_init(simplestring* string)
  82. * FUNCTION
  83. * initialize string
  84. * INPUTS
  85. * string - pointer to a simplestring struct that will be initialized
  86. * RESULT
  87. * void
  88. * NOTES
  89. * SEE ALSO
  90. * simplestring_free ()
  91. * simplestring_clear ()
  92. * SOURCE
  93. */
  94. void simplestring_init(simplestring* string) {
  95. memset(string, 0, sizeof(simplestring));
  96. }
  97. /******/
  98. static void simplestring_init_str(simplestring* string) {
  99. string->str = (char*)emalloc(SIMPLESTRING_INCR);
  100. if(string->str) {
  101. string->str[0] = 0;
  102. string->len = 0;
  103. string->size = SIMPLESTRING_INCR;
  104. }
  105. else {
  106. string->size = 0;
  107. }
  108. }
  109. /****f* FUNC/simplestring_clear
  110. * NAME
  111. * simplestring_clear
  112. * SYNOPSIS
  113. * void simplestring_clear(simplestring* string)
  114. * FUNCTION
  115. * clears contents of a string
  116. * INPUTS
  117. * string - the string value to clear
  118. * RESULT
  119. * void
  120. * NOTES
  121. * This function is very fast as it does not de-allocate any memory.
  122. * SEE ALSO
  123. *
  124. * SOURCE
  125. */
  126. void simplestring_clear(simplestring* string) {
  127. if(string->str) {
  128. string->str[0] = 0;
  129. }
  130. string->len = 0;
  131. }
  132. /******/
  133. /****f* FUNC/simplestring_free
  134. * NAME
  135. * simplestring_free
  136. * SYNOPSIS
  137. * void simplestring_free(simplestring* string)
  138. * FUNCTION
  139. * frees contents of a string, if any. Does *not* free the simplestring struct itself.
  140. * INPUTS
  141. * string - value containing string to be free'd
  142. * RESULT
  143. * void
  144. * NOTES
  145. * caller is responsible for allocating and freeing simplestring* struct itself.
  146. * SEE ALSO
  147. * simplestring_init ()
  148. * SOURCE
  149. */
  150. void simplestring_free(simplestring* string) {
  151. if(string && string->str) {
  152. my_free(string->str);
  153. string->len = 0;
  154. }
  155. }
  156. /******/
  157. #ifndef SIZE_MAX
  158. #define SIZE_MAX ((size_t)-1)
  159. #endif
  160. /****f* FUNC/simplestring_addn
  161. * NAME
  162. * simplestring_addn
  163. * SYNOPSIS
  164. * void simplestring_addn(simplestring* string, const char* add, int add_len)
  165. * FUNCTION
  166. * copies n characters from source to target string
  167. * INPUTS
  168. * target - target string
  169. * source - source string
  170. * add_len - number of characters to copy
  171. * RESULT
  172. * void
  173. * NOTES
  174. * SEE ALSO
  175. * simplestring_add ()
  176. * SOURCE
  177. */
  178. void simplestring_addn(simplestring* target, const char* source, size_t add_len) {
  179. size_t newsize = target->size, incr = 0;
  180. if(target && source) {
  181. if(!target->str) {
  182. simplestring_init_str(target);
  183. }
  184. if((SIZE_MAX - add_len) < target->len || (SIZE_MAX - add_len - 1) < target->len) {
  185. /* check for overflows, if there's a potential overflow do nothing */
  186. return;
  187. }
  188. if(target->len + add_len + 1 > target->size) {
  189. /* newsize is current length + new length */
  190. newsize = target->len + add_len + 1;
  191. incr = target->size * 2;
  192. /* align to SIMPLESTRING_INCR increments */
  193. if (incr) {
  194. newsize = newsize - (newsize % incr) + incr;
  195. }
  196. if(newsize < (target->len + add_len + 1)) {
  197. /* some kind of overflow happened */
  198. return;
  199. }
  200. target->str = (char*)erealloc(target->str, newsize);
  201. target->size = target->str ? newsize : 0;
  202. }
  203. if(target->str) {
  204. if(add_len) {
  205. memcpy(target->str + target->len, source, add_len);
  206. }
  207. target->len += add_len;
  208. target->str[target->len] = 0; /* null terminate */
  209. }
  210. }
  211. }
  212. /******/
  213. /****f* FUNC/simplestring_add
  214. * NAME
  215. * simplestring_add
  216. * SYNOPSIS
  217. * void simplestring_add(simplestring* string, const char* add)
  218. * FUNCTION
  219. * appends a string of unknown length from source to target
  220. * INPUTS
  221. * target - the target string to append to
  222. * source - the source string of unknown length
  223. * RESULT
  224. * void
  225. * NOTES
  226. * SEE ALSO
  227. * simplestring_addn ()
  228. * SOURCE
  229. */
  230. void simplestring_add(simplestring* target, const char* source) {
  231. if(target && source) {
  232. simplestring_addn(target, source, strlen(source));
  233. }
  234. }
  235. /******/
  236. /*----------------------
  237. * End String Functions *
  238. *--------------------**/