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