nuklear_string.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. #include "nuklear.h"
  2. #include "nuklear_internal.h"
  3. /* ===============================================================
  4. *
  5. * STRING
  6. *
  7. * ===============================================================*/
  8. #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
  9. NK_API void
  10. nk_str_init_default(struct nk_str *str)
  11. {
  12. struct nk_allocator alloc;
  13. alloc.userdata.ptr = 0;
  14. alloc.alloc = nk_malloc;
  15. alloc.free = nk_mfree;
  16. nk_buffer_init(&str->buffer, &alloc, 32);
  17. str->len = 0;
  18. }
  19. #endif
  20. NK_API void
  21. nk_str_init(struct nk_str *str, const struct nk_allocator *alloc, nk_size size)
  22. {
  23. nk_buffer_init(&str->buffer, alloc, size);
  24. str->len = 0;
  25. }
  26. NK_API void
  27. nk_str_init_fixed(struct nk_str *str, void *memory, nk_size size)
  28. {
  29. nk_buffer_init_fixed(&str->buffer, memory, size);
  30. str->len = 0;
  31. }
  32. NK_API int
  33. nk_str_append_text_char(struct nk_str *s, const char *str, int len)
  34. {
  35. char *mem;
  36. NK_ASSERT(s);
  37. NK_ASSERT(str);
  38. if (!s || !str || !len) return 0;
  39. mem = (char*)nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
  40. if (!mem) return 0;
  41. NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
  42. s->len += nk_utf_len(str, len);
  43. return len;
  44. }
  45. NK_API int
  46. nk_str_append_str_char(struct nk_str *s, const char *str)
  47. {
  48. return nk_str_append_text_char(s, str, nk_strlen(str));
  49. }
  50. NK_API int
  51. nk_str_append_text_utf8(struct nk_str *str, const char *text, int len)
  52. {
  53. int i = 0;
  54. int byte_len = 0;
  55. nk_rune unicode;
  56. if (!str || !text || !len) return 0;
  57. for (i = 0; i < len; ++i)
  58. byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
  59. nk_str_append_text_char(str, text, byte_len);
  60. return len;
  61. }
  62. NK_API int
  63. nk_str_append_str_utf8(struct nk_str *str, const char *text)
  64. {
  65. int byte_len = 0;
  66. int num_runes = 0;
  67. int glyph_len = 0;
  68. nk_rune unicode;
  69. if (!str || !text) return 0;
  70. glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
  71. while (unicode != '\0' && glyph_len) {
  72. glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
  73. byte_len += glyph_len;
  74. num_runes++;
  75. }
  76. nk_str_append_text_char(str, text, byte_len);
  77. return num_runes;
  78. }
  79. NK_API int
  80. nk_str_append_text_runes(struct nk_str *str, const nk_rune *text, int len)
  81. {
  82. int i = 0;
  83. int byte_len = 0;
  84. nk_glyph glyph;
  85. NK_ASSERT(str);
  86. if (!str || !text || !len) return 0;
  87. for (i = 0; i < len; ++i) {
  88. byte_len = nk_utf_encode(text[i], glyph, NK_UTF_SIZE);
  89. if (!byte_len) break;
  90. nk_str_append_text_char(str, glyph, byte_len);
  91. }
  92. return len;
  93. }
  94. NK_API int
  95. nk_str_append_str_runes(struct nk_str *str, const nk_rune *runes)
  96. {
  97. int i = 0;
  98. nk_glyph glyph;
  99. int byte_len;
  100. NK_ASSERT(str);
  101. if (!str || !runes) return 0;
  102. while (runes[i] != '\0') {
  103. byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
  104. nk_str_append_text_char(str, glyph, byte_len);
  105. i++;
  106. }
  107. return i;
  108. }
  109. NK_API int
  110. nk_str_insert_at_char(struct nk_str *s, int pos, const char *str, int len)
  111. {
  112. int i;
  113. void *mem;
  114. char *src;
  115. char *dst;
  116. int copylen;
  117. NK_ASSERT(s);
  118. NK_ASSERT(str);
  119. NK_ASSERT(len >= 0);
  120. if (!s || !str || !len || (nk_size)pos > s->buffer.allocated) return 0;
  121. if ((s->buffer.allocated + (nk_size)len >= s->buffer.memory.size) &&
  122. (s->buffer.type == NK_BUFFER_FIXED)) return 0;
  123. copylen = (int)s->buffer.allocated - pos;
  124. if (!copylen) {
  125. nk_str_append_text_char(s, str, len);
  126. return 1;
  127. }
  128. mem = nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
  129. if (!mem) return 0;
  130. /* memmove */
  131. NK_ASSERT(((int)pos + (int)len + ((int)copylen - 1)) >= 0);
  132. NK_ASSERT(((int)pos + ((int)copylen - 1)) >= 0);
  133. dst = nk_ptr_add(char, s->buffer.memory.ptr, pos + len + (copylen - 1));
  134. src = nk_ptr_add(char, s->buffer.memory.ptr, pos + (copylen-1));
  135. for (i = 0; i < copylen; ++i) *dst-- = *src--;
  136. mem = nk_ptr_add(void, s->buffer.memory.ptr, pos);
  137. NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
  138. s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
  139. return 1;
  140. }
  141. NK_API int
  142. nk_str_insert_at_rune(struct nk_str *str, int pos, const char *cstr, int len)
  143. {
  144. int glyph_len;
  145. nk_rune unicode;
  146. const char *begin;
  147. const char *buffer;
  148. NK_ASSERT(str);
  149. NK_ASSERT(cstr);
  150. NK_ASSERT(len);
  151. if (!str || !cstr || !len) return 0;
  152. begin = nk_str_at_rune(str, pos, &unicode, &glyph_len);
  153. if (!str->len)
  154. return nk_str_append_text_char(str, cstr, len);
  155. buffer = nk_str_get_const(str);
  156. if (!begin) return 0;
  157. return nk_str_insert_at_char(str, (int)(begin - buffer), cstr, len);
  158. }
  159. NK_API int
  160. nk_str_insert_text_char(struct nk_str *str, int pos, const char *text, int len)
  161. {
  162. return nk_str_insert_text_utf8(str, pos, text, len);
  163. }
  164. NK_API int
  165. nk_str_insert_str_char(struct nk_str *str, int pos, const char *text)
  166. {
  167. return nk_str_insert_text_utf8(str, pos, text, nk_strlen(text));
  168. }
  169. NK_API int
  170. nk_str_insert_text_utf8(struct nk_str *str, int pos, const char *text, int len)
  171. {
  172. int i = 0;
  173. int byte_len = 0;
  174. nk_rune unicode;
  175. NK_ASSERT(str);
  176. NK_ASSERT(text);
  177. if (!str || !text || !len) return 0;
  178. for (i = 0; i < len; ++i)
  179. byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
  180. nk_str_insert_at_rune(str, pos, text, byte_len);
  181. return len;
  182. }
  183. NK_API int
  184. nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text)
  185. {
  186. int byte_len = 0;
  187. int num_runes = 0;
  188. int glyph_len = 0;
  189. nk_rune unicode;
  190. if (!str || !text) return 0;
  191. glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
  192. while (unicode != '\0' && glyph_len) {
  193. glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
  194. byte_len += glyph_len;
  195. num_runes++;
  196. }
  197. nk_str_insert_at_rune(str, pos, text, byte_len);
  198. return num_runes;
  199. }
  200. NK_API int
  201. nk_str_insert_text_runes(struct nk_str *str, int pos, const nk_rune *runes, int len)
  202. {
  203. int i = 0;
  204. int byte_len = 0;
  205. nk_glyph glyph;
  206. NK_ASSERT(str);
  207. if (!str || !runes || !len) return 0;
  208. for (i = 0; i < len; ++i) {
  209. byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
  210. if (!byte_len) break;
  211. nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
  212. }
  213. return len;
  214. }
  215. NK_API int
  216. nk_str_insert_str_runes(struct nk_str *str, int pos, const nk_rune *runes)
  217. {
  218. int i = 0;
  219. nk_glyph glyph;
  220. int byte_len;
  221. NK_ASSERT(str);
  222. if (!str || !runes) return 0;
  223. while (runes[i] != '\0') {
  224. byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
  225. nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
  226. i++;
  227. }
  228. return i;
  229. }
  230. NK_API void
  231. nk_str_remove_chars(struct nk_str *s, int len)
  232. {
  233. NK_ASSERT(s);
  234. NK_ASSERT(len >= 0);
  235. if (!s || len < 0 || (nk_size)len > s->buffer.allocated) return;
  236. NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
  237. s->buffer.allocated -= (nk_size)len;
  238. s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
  239. }
  240. NK_API void
  241. nk_str_remove_runes(struct nk_str *str, int len)
  242. {
  243. int index;
  244. const char *begin;
  245. const char *end;
  246. nk_rune unicode;
  247. NK_ASSERT(str);
  248. NK_ASSERT(len >= 0);
  249. if (!str || len < 0) return;
  250. if (len >= str->len) {
  251. str->len = 0;
  252. return;
  253. }
  254. index = str->len - len;
  255. begin = nk_str_at_rune(str, index, &unicode, &len);
  256. end = (const char*)str->buffer.memory.ptr + str->buffer.allocated;
  257. nk_str_remove_chars(str, (int)(end-begin)+1);
  258. }
  259. NK_API void
  260. nk_str_delete_chars(struct nk_str *s, int pos, int len)
  261. {
  262. NK_ASSERT(s);
  263. if (!s || !len || (nk_size)pos > s->buffer.allocated ||
  264. (nk_size)(pos + len) > s->buffer.allocated) return;
  265. if ((nk_size)(pos + len) < s->buffer.allocated) {
  266. /* memmove */
  267. char *dst = nk_ptr_add(char, s->buffer.memory.ptr, pos);
  268. char *src = nk_ptr_add(char, s->buffer.memory.ptr, pos + len);
  269. NK_MEMCPY(dst, src, s->buffer.allocated - (nk_size)(pos + len));
  270. NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
  271. s->buffer.allocated -= (nk_size)len;
  272. } else nk_str_remove_chars(s, len);
  273. s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
  274. }
  275. NK_API void
  276. nk_str_delete_runes(struct nk_str *s, int pos, int len)
  277. {
  278. char *temp;
  279. nk_rune unicode;
  280. char *begin;
  281. char *end;
  282. int unused;
  283. NK_ASSERT(s);
  284. NK_ASSERT(s->len >= pos + len);
  285. if (s->len < pos + len)
  286. len = NK_CLAMP(0, (s->len - pos), s->len);
  287. if (!len) return;
  288. temp = (char *)s->buffer.memory.ptr;
  289. begin = nk_str_at_rune(s, pos, &unicode, &unused);
  290. if (!begin) return;
  291. s->buffer.memory.ptr = begin;
  292. end = nk_str_at_rune(s, len, &unicode, &unused);
  293. s->buffer.memory.ptr = temp;
  294. if (!end) return;
  295. nk_str_delete_chars(s, (int)(begin - temp), (int)(end - begin));
  296. }
  297. NK_API char*
  298. nk_str_at_char(struct nk_str *s, int pos)
  299. {
  300. NK_ASSERT(s);
  301. if (!s || pos > (int)s->buffer.allocated) return 0;
  302. return nk_ptr_add(char, s->buffer.memory.ptr, pos);
  303. }
  304. NK_API char*
  305. nk_str_at_rune(struct nk_str *str, int pos, nk_rune *unicode, int *len)
  306. {
  307. int i = 0;
  308. int src_len = 0;
  309. int glyph_len = 0;
  310. char *text;
  311. int text_len;
  312. NK_ASSERT(str);
  313. NK_ASSERT(unicode);
  314. NK_ASSERT(len);
  315. if (!str || !unicode || !len) return 0;
  316. if (pos < 0) {
  317. *unicode = 0;
  318. *len = 0;
  319. return 0;
  320. }
  321. text = (char*)str->buffer.memory.ptr;
  322. text_len = (int)str->buffer.allocated;
  323. glyph_len = nk_utf_decode(text, unicode, text_len);
  324. while (glyph_len) {
  325. if (i == pos) {
  326. *len = glyph_len;
  327. break;
  328. }
  329. i++;
  330. src_len = src_len + glyph_len;
  331. glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
  332. }
  333. if (i != pos) return 0;
  334. return text + src_len;
  335. }
  336. NK_API const char*
  337. nk_str_at_char_const(const struct nk_str *s, int pos)
  338. {
  339. NK_ASSERT(s);
  340. if (!s || pos > (int)s->buffer.allocated) return 0;
  341. return nk_ptr_add(char, s->buffer.memory.ptr, pos);
  342. }
  343. NK_API const char*
  344. nk_str_at_const(const struct nk_str *str, int pos, nk_rune *unicode, int *len)
  345. {
  346. int i = 0;
  347. int src_len = 0;
  348. int glyph_len = 0;
  349. char *text;
  350. int text_len;
  351. NK_ASSERT(str);
  352. NK_ASSERT(unicode);
  353. NK_ASSERT(len);
  354. if (!str || !unicode || !len) return 0;
  355. if (pos < 0) {
  356. *unicode = 0;
  357. *len = 0;
  358. return 0;
  359. }
  360. text = (char*)str->buffer.memory.ptr;
  361. text_len = (int)str->buffer.allocated;
  362. glyph_len = nk_utf_decode(text, unicode, text_len);
  363. while (glyph_len) {
  364. if (i == pos) {
  365. *len = glyph_len;
  366. break;
  367. }
  368. i++;
  369. src_len = src_len + glyph_len;
  370. glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
  371. }
  372. if (i != pos) return 0;
  373. return text + src_len;
  374. }
  375. NK_API nk_rune
  376. nk_str_rune_at(const struct nk_str *str, int pos)
  377. {
  378. int len;
  379. nk_rune unicode = 0;
  380. nk_str_at_const(str, pos, &unicode, &len);
  381. return unicode;
  382. }
  383. NK_API char*
  384. nk_str_get(struct nk_str *s)
  385. {
  386. NK_ASSERT(s);
  387. if (!s || !s->len || !s->buffer.allocated) return 0;
  388. return (char*)s->buffer.memory.ptr;
  389. }
  390. NK_API const char*
  391. nk_str_get_const(const struct nk_str *s)
  392. {
  393. NK_ASSERT(s);
  394. if (!s || !s->len || !s->buffer.allocated) return 0;
  395. return (const char*)s->buffer.memory.ptr;
  396. }
  397. NK_API int
  398. nk_str_len(struct nk_str *s)
  399. {
  400. NK_ASSERT(s);
  401. if (!s || !s->len || !s->buffer.allocated) return 0;
  402. return s->len;
  403. }
  404. NK_API int
  405. nk_str_len_char(struct nk_str *s)
  406. {
  407. NK_ASSERT(s);
  408. if (!s || !s->len || !s->buffer.allocated) return 0;
  409. return (int)s->buffer.allocated;
  410. }
  411. NK_API void
  412. nk_str_clear(struct nk_str *str)
  413. {
  414. NK_ASSERT(str);
  415. nk_buffer_clear(&str->buffer);
  416. str->len = 0;
  417. }
  418. NK_API void
  419. nk_str_free(struct nk_str *str)
  420. {
  421. NK_ASSERT(str);
  422. nk_buffer_free(&str->buffer);
  423. str->len = 0;
  424. }