summaryrefslogtreecommitdiff
path: root/vendor/nunicode/src/libnu/strings.c
blob: 0eda8cf08f016c4ec8bb8133e50b25c0068fae1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <libnu/defines.h>
#include <libnu/strings.h>

#if defined (NU_WITH_Z_STRINGS) || defined(NU_WITH_N_STRINGS)

static ssize_t _nu_strlen(const char *encoded, const char *limit, nu_read_iterator_t it) {
	ssize_t len = 0;

	const char *p = encoded;
	while (p < limit) {
		uint32_t u = 0;
		p = it(p, &u);

		if (u == 0) {
			break;
		}

		++len;
	}

	return len;
}

static ssize_t _nu_bytelen(const uint32_t *unicode, const uint32_t *limit, nu_write_iterator_t it) {
	ssize_t len = 0;

	const uint32_t *p = unicode;
	while (p < limit) {
		if (*p == 0) {
			break;
		}

		/* nu_write_iterator_t will return offset relative to 0
		 * which is effectively bytes length of codepoint */
		size_t byte_len = (size_t)it(*p, 0);
		len += byte_len;

		++p;
	}

	return len;
}

static ssize_t _nu_strbytelen(const char *encoded, const char *limit, nu_read_iterator_t it) {
	uint32_t u = 0;
	const char *p = encoded;

	while (p < limit) {
		const char *np = it(p, &u);

		if (u == 0) {
			return (p - encoded);
		}

		p = np;
	}

	return 0;
}

#endif /* NU_WITH_N_STRINGS || NU_WITH_Z_STRINGS */

#ifdef NU_WITH_Z_STRINGS

ssize_t nu_strlen(const char *encoded, nu_read_iterator_t it) {
	return _nu_strlen(encoded, NU_UNLIMITED, it);
}

ssize_t nu_bytelen(const uint32_t *unicode, nu_write_iterator_t it) {
	return _nu_bytelen(unicode, NU_UNLIMITED, it);
}

ssize_t nu_strbytelen(const char *encoded, nu_read_iterator_t it) {
	return _nu_strbytelen(encoded, NU_UNLIMITED, it);
}

#endif /* NU_WITH_Z_STRINGS */

#ifdef NU_WITH_N_STRINGS

ssize_t nu_strnlen(const char *encoded, size_t max_len, nu_read_iterator_t it) {
	return _nu_strlen(encoded, encoded + max_len, it);
}

ssize_t nu_bytenlen(const uint32_t *unicode, size_t max_len, nu_write_iterator_t it) {
	return _nu_bytelen(unicode, unicode + max_len, it);
}

#endif /* NU_WITH_N_STRINGS */