string_i.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  3. * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include <pj/assert.h>
  20. #include <pj/pool.h>
  21. PJ_IDEF(pj_str_t) pj_str(char *str)
  22. {
  23. pj_str_t dst;
  24. dst.ptr = str;
  25. dst.slen = str ? pj_ansi_strlen(str) : 0;
  26. return dst;
  27. }
  28. PJ_IDEF(pj_str_t*) pj_strdup(pj_pool_t *pool,
  29. pj_str_t *dst,
  30. const pj_str_t *src)
  31. {
  32. pj_assert(src->slen >= 0);
  33. /* Without this, destination will be corrupted */
  34. if (dst == src)
  35. return dst;
  36. if (src->slen > 0) {
  37. dst->ptr = (char*)pj_pool_alloc(pool, src->slen);
  38. pj_memcpy(dst->ptr, src->ptr, src->slen);
  39. }
  40. dst->slen = (src->slen < 0)? 0: src->slen;
  41. return dst;
  42. }
  43. PJ_IDEF(pj_str_t*) pj_strdup_with_null( pj_pool_t *pool,
  44. pj_str_t *dst,
  45. const pj_str_t *src)
  46. {
  47. pj_ssize_t src_slen = src->slen;
  48. pj_assert(src->slen >= 0);
  49. /* Check if the source's length is invalid */
  50. if (src_slen < 0)
  51. src_slen = 0;
  52. dst->ptr = (char*)pj_pool_alloc(pool, src_slen+1);
  53. if (src_slen) {
  54. pj_memcpy(dst->ptr, src->ptr, src_slen);
  55. }
  56. dst->slen = src_slen;
  57. dst->ptr[dst->slen] = '\0';
  58. return dst;
  59. }
  60. PJ_IDEF(pj_str_t*) pj_strdup2(pj_pool_t *pool,
  61. pj_str_t *dst,
  62. const char *src)
  63. {
  64. dst->slen = src ? pj_ansi_strlen(src) : 0;
  65. if (dst->slen) {
  66. dst->ptr = (char*)pj_pool_alloc(pool, dst->slen);
  67. pj_memcpy(dst->ptr, src, dst->slen);
  68. } else {
  69. dst->ptr = NULL;
  70. }
  71. return dst;
  72. }
  73. PJ_IDEF(pj_str_t*) pj_strdup2_with_null( pj_pool_t *pool,
  74. pj_str_t *dst,
  75. const char *src)
  76. {
  77. dst->slen = src ? pj_ansi_strlen(src) : 0;
  78. dst->ptr = (char*)pj_pool_alloc(pool, dst->slen+1);
  79. if (dst->slen) {
  80. pj_memcpy(dst->ptr, src, dst->slen);
  81. }
  82. dst->ptr[dst->slen] = '\0';
  83. return dst;
  84. }
  85. PJ_IDEF(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src)
  86. {
  87. pj_str_t temp;
  88. pj_strdup2(pool, &temp, src);
  89. return temp;
  90. }
  91. PJ_IDEF(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src )
  92. {
  93. dst->ptr = src->ptr;
  94. dst->slen = src->slen;
  95. return dst;
  96. }
  97. PJ_IDEF(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src)
  98. {
  99. pj_assert(src->slen >= 0);
  100. dst->slen = (src->slen < 0)? 0: src->slen;
  101. if (src->slen > 0)
  102. pj_memcpy(dst->ptr, src->ptr, src->slen);
  103. return dst;
  104. }
  105. PJ_IDEF(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src)
  106. {
  107. dst->slen = src ? pj_ansi_strlen(src) : 0;
  108. if (dst->slen > 0)
  109. pj_memcpy(dst->ptr, src, dst->slen);
  110. return dst;
  111. }
  112. PJ_IDEF(pj_str_t*) pj_strncpy( pj_str_t *dst, const pj_str_t *src,
  113. pj_ssize_t max)
  114. {
  115. pj_assert(src->slen >= 0);
  116. pj_assert(max >= 0);
  117. if (max > src->slen) max = src->slen;
  118. if (max > 0)
  119. pj_memcpy(dst->ptr, src->ptr, max);
  120. dst->slen = (max < 0)? 0: max;
  121. return dst;
  122. }
  123. PJ_IDEF(pj_str_t*) pj_strncpy_with_null( pj_str_t *dst, const pj_str_t *src,
  124. pj_ssize_t max)
  125. {
  126. pj_assert(src->slen >= 0);
  127. pj_assert(max > 0);
  128. if (max <= src->slen)
  129. max = (max > 0)? max-1: 0;
  130. else
  131. max = (src->slen < 0)? 0: src->slen;
  132. if (max > 0)
  133. pj_memcpy(dst->ptr, src->ptr, max);
  134. dst->ptr[max] = '\0';
  135. dst->slen = max;
  136. return dst;
  137. }
  138. PJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2)
  139. {
  140. pj_assert(str1->slen >= 0);
  141. pj_assert(str2->slen >= 0);
  142. if (str1->slen <= 0) {
  143. return str2->slen<=0 ? 0 : -1;
  144. } else if (str2->slen <= 0) {
  145. return 1;
  146. } else {
  147. pj_size_t min = (str1->slen < str2->slen)? str1->slen : str2->slen;
  148. int res = pj_memcmp(str1->ptr, str2->ptr, min);
  149. if (res == 0) {
  150. return (str1->slen < str2->slen) ? -1 :
  151. (str1->slen == str2->slen ? 0 : 1);
  152. } else {
  153. return res;
  154. }
  155. }
  156. }
  157. PJ_IDEF(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2,
  158. pj_size_t len)
  159. {
  160. pj_str_t copy1, copy2;
  161. pj_assert(str1->slen >= 0);
  162. pj_assert(str2->slen >= 0);
  163. if (len < (unsigned)str1->slen && str1->slen > 0) {
  164. copy1.ptr = str1->ptr;
  165. copy1.slen = len;
  166. str1 = &copy1;
  167. }
  168. if (len < (unsigned)str2->slen && str2->slen > 0) {
  169. copy2.ptr = str2->ptr;
  170. copy2.slen = len;
  171. str2 = &copy2;
  172. }
  173. return pj_strcmp(str1, str2);
  174. }
  175. PJ_IDEF(int) pj_strncmp2( const pj_str_t *str1, const char *str2,
  176. pj_size_t len)
  177. {
  178. pj_str_t copy2;
  179. if (str2) {
  180. copy2.ptr = (char*)str2;
  181. copy2.slen = pj_ansi_strlen(str2);
  182. } else {
  183. copy2.slen = 0;
  184. }
  185. return pj_strncmp(str1, &copy2, len);
  186. }
  187. PJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 )
  188. {
  189. pj_str_t copy2;
  190. if (str2) {
  191. copy2.ptr = (char*)str2;
  192. copy2.slen = pj_ansi_strlen(str2);
  193. } else {
  194. copy2.ptr = NULL;
  195. copy2.slen = 0;
  196. }
  197. return pj_strcmp(str1, &copy2);
  198. }
  199. PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)
  200. {
  201. pj_assert(str1->slen >= 0);
  202. pj_assert(str2->slen >= 0);
  203. if (str1->slen <= 0) {
  204. return str2->slen<=0 ? 0 : -1;
  205. } else if (str2->slen <= 0) {
  206. return 1;
  207. } else {
  208. pj_size_t min = (str1->slen < str2->slen)? str1->slen : str2->slen;
  209. int res = pj_ansi_strnicmp(str1->ptr, str2->ptr, min);
  210. if (res == 0) {
  211. return (str1->slen < str2->slen) ? -1 :
  212. (str1->slen == str2->slen ? 0 : 1);
  213. } else {
  214. return res;
  215. }
  216. }
  217. }
  218. #if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0
  219. PJ_IDEF(int) strnicmp_alnum( const char *str1, const char *str2,
  220. int len)
  221. {
  222. if (len==0)
  223. return 0;
  224. else {
  225. register const pj_uint32_t *p1 = (pj_uint32_t*)str1,
  226. *p2 = (pj_uint32_t*)str2;
  227. while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
  228. ++p1, ++p2, len-=4;
  229. if (len > 3)
  230. return -1;
  231. #if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
  232. else if (len==3)
  233. return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
  234. else if (len==2)
  235. return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
  236. else if (len==1)
  237. return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
  238. #else
  239. else if (len==3)
  240. return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
  241. else if (len==2)
  242. return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
  243. else if (len==1)
  244. return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
  245. #endif
  246. else
  247. return 0;
  248. }
  249. }
  250. PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2)
  251. {
  252. register int len = str1->slen;
  253. if (len != str2->slen) {
  254. return (len < str2->slen) ? -1 : 1;
  255. } else if (len == 0) {
  256. return 0;
  257. } else {
  258. register const pj_uint32_t *p1 = (pj_uint32_t*)str1->ptr,
  259. *p2 = (pj_uint32_t*)str2->ptr;
  260. while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
  261. ++p1, ++p2, len-=4;
  262. if (len > 3)
  263. return -1;
  264. #if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
  265. else if (len==3)
  266. return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
  267. else if (len==2)
  268. return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
  269. else if (len==1)
  270. return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
  271. #else
  272. else if (len==3)
  273. return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
  274. else if (len==2)
  275. return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
  276. else if (len==1)
  277. return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
  278. #endif
  279. else
  280. return 0;
  281. }
  282. }
  283. #endif /* PJ_HAS_STRICMP_ALNUM */
  284. PJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2)
  285. {
  286. pj_str_t copy2;
  287. if (str2) {
  288. copy2.ptr = (char*)str2;
  289. copy2.slen = pj_ansi_strlen(str2);
  290. } else {
  291. copy2.ptr = NULL;
  292. copy2.slen = 0;
  293. }
  294. return pj_stricmp(str1, &copy2);
  295. }
  296. PJ_IDEF(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2,
  297. pj_size_t len)
  298. {
  299. pj_str_t copy1, copy2;
  300. if (len < (unsigned)str1->slen && str1->slen > 0) {
  301. copy1.ptr = str1->ptr;
  302. copy1.slen = len;
  303. str1 = &copy1;
  304. }
  305. if (len < (unsigned)str2->slen && str2->slen > 0) {
  306. copy2.ptr = str2->ptr;
  307. copy2.slen = len;
  308. str2 = &copy2;
  309. }
  310. return pj_stricmp(str1, str2);
  311. }
  312. PJ_IDEF(int) pj_strnicmp2( const pj_str_t *str1, const char *str2,
  313. pj_size_t len)
  314. {
  315. pj_str_t copy2;
  316. if (str2) {
  317. copy2.ptr = (char*)str2;
  318. copy2.slen = pj_ansi_strlen(str2);
  319. } else {
  320. copy2.slen = 0;
  321. }
  322. return pj_strnicmp(str1, &copy2, len);
  323. }
  324. PJ_IDEF(void) pj_strcat(pj_str_t *dst, const pj_str_t *src)
  325. {
  326. pj_assert(src->slen >= 0);
  327. pj_assert(dst->slen >= 0);
  328. if (src->slen > 0 && dst->slen >= 0) {
  329. pj_memcpy(dst->ptr + dst->slen, src->ptr, src->slen);
  330. dst->slen += src->slen;
  331. }
  332. }
  333. PJ_IDEF(void) pj_strcat2(pj_str_t *dst, const char *str)
  334. {
  335. pj_size_t len = str? pj_ansi_strlen(str) : 0;
  336. pj_assert(dst->slen >= 0);
  337. if (len && dst->slen >= 0) {
  338. pj_memcpy(dst->ptr + dst->slen, str, len);
  339. dst->slen += len;
  340. }
  341. }
  342. PJ_IDEF(pj_str_t*) pj_strtrim( pj_str_t *str )
  343. {
  344. pj_strltrim(str);
  345. pj_strrtrim(str);
  346. return str;
  347. }