70 lines
1.7 KiB
C
70 lines
1.7 KiB
C
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||
|
/* Copyright © 2022 Gregory Lirent */
|
||
|
|
||
|
#include "build.h"
|
||
|
|
||
|
const char* fromchar_unicode(unsigned int* uc, const char* s) {
|
||
|
unsigned char* p;
|
||
|
unsigned int v;
|
||
|
unsigned char n;
|
||
|
|
||
|
if (*(p = (void*)s) <= 0x7f) {
|
||
|
*uc = *s;
|
||
|
return s + 1;
|
||
|
}
|
||
|
|
||
|
memcpy(&v, s, 4);
|
||
|
|
||
|
*uc = 0;
|
||
|
|
||
|
if (IS_LITTLE_ENDIAN) {
|
||
|
if ((v&0x0000c0e0) == 0x000080c0) {
|
||
|
n = 2;
|
||
|
*uc |= *(p++)&0x1f;
|
||
|
} else {
|
||
|
if ((v&0x00c0c0f0) == 0x008080e0) {
|
||
|
n = 3;
|
||
|
*uc |= *(p++)&0x0f;
|
||
|
} else if ((v&0xc0c0c0f8) == 0x808080f0) {
|
||
|
n = 4;
|
||
|
*uc |= *(p++)&0x07;
|
||
|
*uc <<= 6;
|
||
|
*uc |= *(p++)&0x3f;
|
||
|
} else return (void*)(size_t)(*uc = 0);
|
||
|
|
||
|
*uc <<= 6;
|
||
|
*uc |= *(p++)&0x3f;
|
||
|
}
|
||
|
} else {
|
||
|
if ((v&0xe0c00000) == 0xc0800000) {
|
||
|
n = 2;
|
||
|
*uc |= *(p++)&0x1f;
|
||
|
} else {
|
||
|
if ((v&0xf8c0c0c0) == 0xf0808080) {
|
||
|
n = 3;
|
||
|
*uc |= *(p++)&0x0f;
|
||
|
} else if ((v&0xf0c0c000) == 0xe0808000) {
|
||
|
n = 4;
|
||
|
*uc |= *(p++)&0x07;
|
||
|
*uc <<= 6;
|
||
|
*uc |= *(p++)&0x3f;
|
||
|
} else return (void*)(size_t)(*uc = 0);
|
||
|
|
||
|
*uc <<= 6;
|
||
|
*uc |= *(p++)&0x3f;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*uc <<= 6;
|
||
|
*uc |= *(p++)&0x3f;
|
||
|
|
||
|
#ifndef UNICODE_CHARSIZE_CHECK_DISABLE
|
||
|
if ((n == 2 && *uc > 0x0007ff) ||
|
||
|
(n == 3 && *uc > 0x00ffff) ||
|
||
|
(n == 4 && *uc > 0x10ffff))
|
||
|
return (void*)(size_t)(*uc = 0);
|
||
|
#endif
|
||
|
|
||
|
return s + n;
|
||
|
}
|