blob: db66040858320aeb5c0fd92936a3aef486c52549 (
plain) (
blame)
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
|
/* See LICENSE file for copyright and license details. */
#include "lib-common.h"
size_t
libcharconv_decode_utf8_(const char *s, size_t slen, uint_least32_t *cp)
{
uint_least32_t min, max;
size_t i, n;
if (slen < 1u)
return 0u;
if (!(s[0] & 0x80)) {
*cp = (uint_least32_t)s[0];
return 1u;
} else if ((s[0] & 0xE0) == 0xC0) {
*cp = (uint_least32_t)s[0] & 0x3Fu;
n = 2u;
min = UINT32_C(0x80);
max = UINT32_C(0x800);
} else if ((s[0] & 0xF0) == 0xE0) {
*cp = (uint_least32_t)s[0] & 0x1Fu;
n = 3u;
min = UINT32_C(0x800);
max = UINT32_C(0x10000);
} else if ((s[0] & 0xF8) == 0xF0) {
*cp = (uint_least32_t)s[0] & 0x0Fu;
n = 4u;
min = UINT32_C(0x10000);
max = UINT32_C(0x110000);
} else {
return 0u;
}
if (slen < n)
return n;
for (i = 1u; i < n; i++) {
*cp <<= 6;
*cp |= (uint_least32_t)s[i] & 0x3Fu;
}
if (min > *cp || *cp >= max)
return 0u;
return n;
}
|