XenevaOS
Loading...
Searching...
No Matches
utf.h
Go to the documentation of this file.
1
32#ifndef __UTF_H__
33#define __UTF_H__
34
35#include <stdint.h>
36
37#define UTF8_1BYTE_CODEMAX 0x7F
38#define UTF8_2BYTE_CODEMAX 0x7FF
39#define UTF8_3BYTE_CODEMAX 0xFFFF
40#define UTF8_4BYTE_CODEMAX 0x10FFFF
41
42#define UTF8_1BYTE_MASK 0x80
43#define UTF8_2BYTE_MASK 0xE0
44#define UTF8_3BYTE_MASK 0xF0
45#define UTF8_4BYTE_MASK 0xF8
46#define UTF8_EXTBYTE_MASK 0xC0
47
48#define UTF8_1BYTE_PREFIX 0x00
49#define UTF8_2BYTE_PREFIX 0xC0
50#define UTF8_3BYTE_PREFIX 0xE0
51#define UTF8_4BYTE_PREFIX 0xF0
52#define UTF8_EXTBYTE_PREFIX 0x80
53
54#define UTF8_IS_1BYTE(ptr) ((ptr[0] & UTF8_1BYTE_MASK) == UTF8_1BYTE_PREFIX)
55
56#define UTF8_IS_2BYTE(ptr) \
57 (((ptr[0] & UTF8_2BYTE_MASK) == UTF8_2BYTE_PREFIX) && \
58 ((ptr[1] & UTF8_EXTBYTE_MASK) == UTF8_EXTBYTE_PREFIX))
59
60#define UTF8_IS_3BYTE(ptr) \
61 (((ptr[0] & UTF8_3BYTE_MASK) == UTF8_3BYTE_PREFIX) && \
62 (((ptr[1] | ptr[2]) & UTF8_EXTBYTE_MASK) == UTF8_EXTBYTE_PREFIX))
63
64#define UTF8_IS_4BYTE(ptr) \
65 (((ptr[0] & UTF8_4BYTE_MASK) == UTF8_4BYTE_PREFIX) && \
66 (((ptr[1] | ptr[2] | ptr[3]) & UTF8_EXTBYTE_MASK) == UTF8_EXTBYTE_PREFIX))
67
68static inline unsigned utf8CharToUnicode(const char* ptr, unsigned len) {
69 unsigned code = 0;
70
71 if ((len >= 1) && UTF8_IS_1BYTE(ptr)) {
72 code = (unsigned)(ptr[0] & (char)~UTF8_1BYTE_MASK);
73 } else if ((len >= 2) && UTF8_IS_2BYTE(ptr)) {
74 code = (((unsigned)(ptr[0] & (char)~UTF8_2BYTE_MASK) << 6) |
75 (ptr[1] & (char)~UTF8_EXTBYTE_MASK));
76 } else if ((len >= 3) && UTF8_IS_3BYTE(ptr)) {
77 code = (((unsigned)(ptr[0] & (char)~UTF8_3BYTE_MASK) << 12) |
78 ((unsigned)(ptr[1] & (char)~UTF8_EXTBYTE_MASK) << 6) |
79 (ptr[2] & (char)~UTF8_EXTBYTE_MASK));
80 } else if ((len >= 4) && UTF8_IS_4BYTE(ptr)) {
81 code = (((unsigned)(ptr[0] & (char)~UTF8_4BYTE_MASK) << 18) |
82 ((unsigned)(ptr[1] & (char)~UTF8_EXTBYTE_MASK) << 12) |
83 ((unsigned)(ptr[2] & (char)~UTF8_EXTBYTE_MASK) << 6) |
84 (ptr[3] & (char)~UTF8_EXTBYTE_MASK));
85 }
86
87 return (code);
88}
89
90static inline unsigned utf8CodeWidth(unsigned code) {
91 if (code <= UTF8_1BYTE_CODEMAX)
92 return (1);
93 else if (code <= UTF8_2BYTE_CODEMAX)
94 return (2);
95 else if (code <= UTF8_3BYTE_CODEMAX)
96 return (3);
97 else if (code <= UTF8_4BYTE_CODEMAX)
98 return (4);
99 else
100 return (0);
101}
102
103static inline void unicodeToUtf8Char(unsigned code, unsigned char* ptr, unsigned len) {
104 unsigned codeWidth = utf8CodeWidth(code);
105
106 if ((codeWidth == 1) && (len >= codeWidth)) {
107 ptr[0] = (code & UTF8_1BYTE_CODEMAX);
108 } else if ((codeWidth == 2) && (len >= codeWidth)) {
109 ptr[0] = (UTF8_2BYTE_PREFIX | ((code & 0x07D0) >> 6));
110 ptr[1] = (UTF8_EXTBYTE_PREFIX | (code & 0x003F));
111 } else if ((codeWidth == 3) && (len >= codeWidth)) {
112 ptr[0] = (UTF8_3BYTE_PREFIX | ((code & 0xF000) >> 12));
113 ptr[1] = (UTF8_EXTBYTE_PREFIX | ((code & 0x0FD0) >> 6));
114 ptr[2] = (UTF8_EXTBYTE_PREFIX | (code & 0x003F));
115 } else if ((codeWidth == 4) && (len >= codeWidth)) {
116 ptr[0] = (UTF8_4BYTE_PREFIX | ((code & 0x001D0000) >> 18));
117 ptr[1] = (UTF8_EXTBYTE_PREFIX | ((code & 0x0003F000) >> 12));
118 ptr[2] = (UTF8_EXTBYTE_PREFIX | ((code & 0x00000FD0) >> 6));
119 ptr[3] = (UTF8_EXTBYTE_PREFIX | (code & 0x0000003F));
120 }
121}
122
123#define UTF8_ACCEPT 0
124#define UTF8_REJECT 1
125
126static uint32_t decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
127 static int state_table[32] = {
128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xxxxxxx */
129 1, 1, 1, 1, 1, 1, 1, 1, /* 10xxxxxx */
130 2, 2, 2, 2, /* 110xxxxx */
131 3, 3, /* 1110xxxx */
132 4, /* 11110xxx */
133 1 /* 11111xxx */
134 };
135
136 static int mask_bytes[32] = {0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
137 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x00};
139
140 static int next[5] = {0, 1, 0, 2, 3};
141
142 if (*state == UTF8_ACCEPT) {
143 *codep = byte & mask_bytes[byte >> 3];
144 *state = state_table[byte >> 3];
145 } else if (*state > 0) {
146 *codep = (byte & 0x3F) | (*codep << 6);
147 *state = next[*state];
148 }
149 return *state;
150 //return 0;
151}
152
153#endif
unsigned int uint32_t
Definition acefiex.h:163
#define UTF8_IS_4BYTE(ptr)
Definition utf.h:64
#define UTF8_3BYTE_PREFIX
Definition utf.h:50
#define UTF8_2BYTE_PREFIX
Definition utf.h:49
#define UTF8_EXTBYTE_MASK
Definition utf.h:46
#define UTF8_4BYTE_PREFIX
Definition utf.h:51
#define UTF8_3BYTE_CODEMAX
Definition utf.h:39
#define UTF8_IS_2BYTE(ptr)
Definition utf.h:56
#define UTF8_1BYTE_CODEMAX
Definition utf.h:37
#define UTF8_ACCEPT
Definition utf.h:123
#define UTF8_IS_3BYTE(ptr)
Definition utf.h:60
#define UTF8_IS_1BYTE(ptr)
Definition utf.h:54
#define UTF8_4BYTE_CODEMAX
Definition utf.h:40
#define UTF8_EXTBYTE_PREFIX
Definition utf.h:52
#define UTF8_2BYTE_CODEMAX
Definition utf.h:38