This repository has been archived by the owner on Jul 13, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utf8.c
84 lines (72 loc) · 1.97 KB
/
utf8.c
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
// Adapted from https://github.com/nsf/termbox/blob/a0e450500b3f07ddd172ac64e48a59129a8878fb/src/utf8.c
#include <stdint.h>
#include "mlbuf.h"
static const unsigned char utf8_length[256] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
};
static const unsigned char utf8_mask[6] = {
0x7F,
0x1F,
0x0F,
0x07,
0x03,
0x01
};
int utf8_char_length(char c) {
return utf8_length[(unsigned char)c];
}
int utf8_char_to_unicode(uint32_t *out, const char *c, const char *stop) {
if (*c == 0)
return -1;
int i;
unsigned char len = utf8_char_length(*c);
unsigned char mask = utf8_mask[len-1];
uint32_t result = c[0] & mask;
for (i = 1; i < len; ++i) {
if (stop && c + i >= stop) {
len -= (len - i);
break;
}
result <<= 6;
result |= c[i] & 0x3f;
}
*out = result;
return (int)len;
}
int utf8_unicode_to_char(char *out, uint32_t c) {
int len = 0;
int first;
int i;
if (c < 0x80) {
first = 0;
len = 1;
} else if (c < 0x800) {
first = 0xc0;
len = 2;
} else if (c < 0x10000) {
first = 0xe0;
len = 3;
} else if (c < 0x200000) {
first = 0xf0;
len = 4;
} else if (c < 0x4000000) {
first = 0xf8;
len = 5;
} else {
first = 0xfc;
len = 6;
}
for (i = len - 1; i > 0; --i) {
out[i] = (c & 0x3f) | 0x80;
c >>= 6;
}
out[0] = c | first;
return len;
}