2025-10-09 10:46:09 +00:00
|
|
|
/* $Id$ */
|
|
|
|
|
#include <Mw/Milsko.h>
|
|
|
|
|
|
|
|
|
|
/* this code was taken from my old code... :) */
|
|
|
|
|
|
|
|
|
|
#define CAST_I32(x) ((int)(x))
|
|
|
|
|
|
|
|
|
|
static int utf8_count(unsigned char c) {
|
|
|
|
|
if(c < 0x80) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if(0xc2 <= c && c < 0xe0) {
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
|
|
|
|
if(0xe0 <= c && c < 0xf0) {
|
|
|
|
|
return 3;
|
|
|
|
|
}
|
|
|
|
|
if(0xf0 <= c && c < 0xf8) {
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int utf8_later(unsigned char c) {
|
|
|
|
|
return 0x80 <= c && c < 0xc0;
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-09 10:47:36 +00:00
|
|
|
int MwUTF8ToUTF32(const char* input, int* output) {
|
2025-10-09 10:46:09 +00:00
|
|
|
const unsigned char* inbuf = (const unsigned char*)input;
|
|
|
|
|
int b = utf8_count(inbuf[0]);
|
|
|
|
|
if(b == 0) return 0;
|
|
|
|
|
|
|
|
|
|
if(b == 1) *output = inbuf[0];
|
|
|
|
|
if(b == 2) {
|
|
|
|
|
if(!utf8_later(inbuf[1])) return 0;
|
|
|
|
|
if((inbuf[0] & 0x1e) == 0) return 0;
|
|
|
|
|
|
|
|
|
|
*output = CAST_I32(inbuf[0] & 0x1f) << 6;
|
|
|
|
|
*output |= CAST_I32(inbuf[1] & 0x3f);
|
|
|
|
|
}
|
|
|
|
|
if(b == 3) {
|
|
|
|
|
if(!utf8_later(inbuf[1]) || !utf8_later(inbuf[2])) return 0;
|
|
|
|
|
if((inbuf[0] & 0x0f) == 0 && (inbuf[1] & 0x20) == 0) return 0;
|
|
|
|
|
|
|
|
|
|
*output = CAST_I32(inbuf[0] & 0x0f) << 12;
|
|
|
|
|
*output |= CAST_I32(inbuf[1] & 0x3f) << 6;
|
|
|
|
|
*output |= CAST_I32(inbuf[2] & 0x3f);
|
|
|
|
|
}
|
|
|
|
|
if(b == 4) {
|
|
|
|
|
if(!utf8_later(inbuf[1]) || !utf8_later(inbuf[2]) || !utf8_later(inbuf[3])) return 0;
|
|
|
|
|
if((inbuf[0] & 0x07) == 0 && (inbuf[1] & 0x30) == 0) return 0;
|
|
|
|
|
|
|
|
|
|
*output = CAST_I32(inbuf[0] & 0x07) << 18;
|
|
|
|
|
*output |= CAST_I32(inbuf[1] & 0x3f) << 12;
|
|
|
|
|
*output |= CAST_I32(inbuf[2] & 0x3f) << 6;
|
|
|
|
|
*output |= CAST_I32(inbuf[3] & 0x3f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return b;
|
|
|
|
|
}
|
2025-10-09 10:57:21 +00:00
|
|
|
|
|
|
|
|
int MwUTF8Length(const char* input) {
|
|
|
|
|
int out;
|
|
|
|
|
int len = 0;
|
|
|
|
|
|
|
|
|
|
while(input[0] != 0) {
|
|
|
|
|
int new;
|
|
|
|
|
|
|
|
|
|
input += (new = MwUTF8ToUTF32(input, &out));
|
|
|
|
|
len++;
|
|
|
|
|
|
|
|
|
|
if(new == 0) return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return len;
|
|
|
|
|
}
|
2025-10-09 11:21:39 +00:00
|
|
|
|
|
|
|
|
int MwUTF8Copy(const char* src, int srcskip, char* dst, int dstskip, int len){
|
|
|
|
|
int i;
|
|
|
|
|
int out;
|
|
|
|
|
int total = 0;
|
|
|
|
|
for(i = 0; i < srcskip; i++) src += MwUTF8ToUTF32(src, &out);
|
|
|
|
|
for(i = 0; i < dstskip; i++) dst += MwUTF8ToUTF32(dst, &out);
|
|
|
|
|
for(i = 0; i < len; i++){
|
|
|
|
|
int len = MwUTF8ToUTF32(src, &out);
|
|
|
|
|
|
|
|
|
|
memcpy(dst, src, len);
|
|
|
|
|
|
|
|
|
|
src += len;
|
|
|
|
|
dst += len;
|
|
|
|
|
total += len;
|
|
|
|
|
}
|
|
|
|
|
dst[total] = 0;
|
|
|
|
|
|
|
|
|
|
return total;
|
|
|
|
|
}
|