mirror of
https://github.com/Ed94/perfaware.git
synced 2026-08-14 11:28:08 +00:00
73 lines
2.0 KiB
C
73 lines
2.0 KiB
C
#ifdef INTELLISENSE_DIRECTIVES
|
|
# pragma once
|
|
# include "dsl.h"
|
|
#endif
|
|
|
|
typedef struct UnicodeDecode UnicodeDecode;
|
|
struct UnicodeDecode {
|
|
U4 inc;
|
|
U4 codepoint;
|
|
};
|
|
|
|
RO_ global U1 utf8_class[32] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,3,3,4,5, };
|
|
|
|
FI_ void u64_to_hex(U8 val, char* buf, S4 chars) {
|
|
static const char hex_chars[] = "0123456789ABCDEF";
|
|
for(S1 i = chars - 1; i >= 0; --i) { buf[i] = hex_chars[val & 0xF]; val >>= 4; }
|
|
}
|
|
|
|
internal UnicodeDecode
|
|
utf8_decode(U1* str, U1 max) {
|
|
UnicodeDecode result = {1, Max_U4};
|
|
U1 byte = str[0];
|
|
U1 byte_class = utf8_class[byte >> 3];
|
|
switch(byte_class) {
|
|
case 1: { result.codepoint = byte; } break;
|
|
case 2: if (1 < max) {
|
|
U1 cont_byte = str[1];
|
|
if(utf8_class[cont_byte >> 3] == 0) {
|
|
result.codepoint = (byte & Bitmask_5) << 6;
|
|
result.codepoint |= (cont_byte & Bitmask_6);
|
|
result.inc = 2;
|
|
}
|
|
} break;
|
|
case 3: if(2 < max) {
|
|
U1 cont_byte[2] = {str[1], str[2]};
|
|
if ( utf8_class[cont_byte[0] >> 3] == 0
|
|
&& utf8_class[cont_byte[1] >> 3] == 0) {
|
|
result.codepoint = (byte & Bitmask_4) << 12;
|
|
result.codepoint |= ((cont_byte[0] & Bitmask_6) << 6);
|
|
result.codepoint |= (cont_byte[1] & Bitmask_6);
|
|
result.inc = 3;
|
|
}
|
|
}break;
|
|
case 4: if(3 < max) {
|
|
U1 cont_byte[3] = {str[1], str[2], str[3]};
|
|
if ( utf8_class[cont_byte[0] >> 3] == 0
|
|
&& utf8_class[cont_byte[1] >> 3] == 0
|
|
&& utf8_class[cont_byte[2] >> 3] == 0) {
|
|
result.codepoint = (byte & Bitmask_3) << 18;
|
|
result.codepoint |= ((cont_byte[0] & Bitmask_6) << 12);
|
|
result.codepoint |= ((cont_byte[1] & Bitmask_6) << 6);
|
|
result.codepoint |= (cont_byte[2] & Bitmask_6);
|
|
result.inc = 4;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
I_ U4
|
|
utf16_encode(U2* str, U4 codepoint) {
|
|
U4 inc = 1;
|
|
if (codepoint == Max_U4) { str[0] = (U2)'?'; }
|
|
else if (codepoint < 0x10000) { str[0] = (U2)codepoint; }
|
|
else {
|
|
U4 v = codepoint - 0x10000;
|
|
str[0] = Csafe_u2u4(0xD800 + (v >> 10));
|
|
str[1] = Csafe_u2u4(0xDC00 + (v & Bitmask_10));
|
|
inc = 2;
|
|
}
|
|
return inc;
|
|
}
|