several optimization

This commit is contained in:
Nishi 2026-09-23 13:24:26 +09:00
commit c52b21c9ee
12 changed files with 214 additions and 111 deletions

View file

@ -94,46 +94,60 @@ static int utf8_later(unsigned char c) {
#define CAST_I32(x) ((int)(x))
int sj4_utf8_read(const unsigned char* in, int* output) {
u_char c = in[0];
u_int n = 0;
if(c < 0x80) {
*output = c;
return 1;
} else if(0xc2 <= c && c < 0xe0) {
if(!utf8_later(in[1])) return 0;
if((in[0] & 0x1e) == 0) return 0;
n = CAST_I32(in[0] & 0x1f) << 6;
n |= CAST_I32(in[1] & 0x3f);
*output = n;
return 2;
} else if(0xe0 <= c && c < 0xf0) {
if(!utf8_later(in[1]) || !utf8_later(in[2])) return 0;
if((in[0] & 0x0f) == 0 && (in[1] & 0x20) == 0) return 0;
n = CAST_I32(in[0] & 0x0f) << 12;
n |= CAST_I32(in[1] & 0x3f) << 6;
n |= CAST_I32(in[2] & 0x3f);
*output = n;
return 3;
} else if(0xf0 <= c && c < 0xf8) {
if(!utf8_later(in[1]) || !utf8_later(in[2]) || !utf8_later(in[3])) return 0;
if((in[0] & 0x07) == 0 && (in[1] & 0x30) == 0) return 0;
n = CAST_I32(in[0] & 0x07) << 18;
n |= CAST_I32(in[1] & 0x3f) << 12;
n |= CAST_I32(in[2] & 0x3f) << 6;
n |= CAST_I32(in[3] & 0x3f);
*output = n;
return 4;
}
return 0;
}
int sj4_from_utf8(u_char* out, const u_char* in, int len) {
const u_char* o_in = in;
u_char* o_out = out;
while((in - o_in) < len) {
u_char c = *in;
u_int n = 0;
int n;
if(c < 0x80) {
n = c;
in += 1;
} else if(0xc2 <= c && c < 0xe0) {
if(!utf8_later(in[1])) return 0;
if((in[0] & 0x1e) == 0) return 0;
n = CAST_I32(in[0] & 0x1f) << 6;
n |= CAST_I32(in[1] & 0x3f);
in += 2;
} else if(0xe0 <= c && c < 0xf0) {
if(!utf8_later(in[1]) || !utf8_later(in[2])) return 0;
if((in[0] & 0x0f) == 0 && (in[1] & 0x20) == 0) return 0;
n = CAST_I32(in[0] & 0x0f) << 12;
n |= CAST_I32(in[1] & 0x3f) << 6;
n |= CAST_I32(in[2] & 0x3f);
in += 3;
} else if(0xf0 <= c && c < 0xf8) {
if(!utf8_later(in[1]) || !utf8_later(in[2]) || !utf8_later(in[3])) return 0;
if((in[0] & 0x07) == 0 && (in[1] & 0x30) == 0) return 0;
n = CAST_I32(in[0] & 0x07) << 18;
n |= CAST_I32(in[1] & 0x3f) << 12;
n |= CAST_I32(in[2] & 0x3f) << 6;
n |= CAST_I32(in[3] & 0x3f);
in += 4;
}
in += sj4_utf8_read(in, &n);
n = ucs_to_euc(n);
@ -151,39 +165,45 @@ static int is_low_urr(wchar_t ch) {
return 0xDC00 <= ch && ch < 0xE000;
}
int sj4_utf16_read(const unsigned char* in, int* output) {
const wchar_t* w_in = (const wchar_t*)in;
if(is_high_surr(w_in[0])) {
if(is_low_urr(w_in[1])) {
*output = 0x10000 + CAST_I32(w_in[0] - 0xd800) * 0x400 + CAST_I32(w_in[1] - 0xdc00);
return 2;
} else if(w_in[1] == 0) {
*output = w_in[0];
return 2;
} else {
return 0;
}
} else if(is_low_urr(w_in[0])) {
if(w_in[1] == 0) {
*output = w_in[0];
return 2;
} else {
return 0;
}
} else {
*output = w_in[0];
return 1;
}
}
int sj4_from_utf16(u_char* out, const u_char* in, int len) {
const wchar_t* w_in = (const wchar_t*)in;
const wchar_t* o_in = w_in;
u_char* o_out = out;
while((w_in - o_in) < len) {
u_int n = 0;
int n = 0;
if(is_high_surr(w_in[0])) {
if(is_low_urr(w_in[1])) {
n = 0x10000 + CAST_I32(w_in[0] - 0xd800) * 0x400 + CAST_I32(w_in[1] - 0xdc00);
w_in += 2;
} else if(w_in[1] == 0) {
n = w_in[0];
w_in += 2;
} else {
return 0;
}
} else if(is_low_urr(w_in[0])) {
if(w_in[1] == 0) {
n = w_in[0];
w_in += 2;
} else {
return 0;
}
} else {
n = w_in[0];
w_in += 1;
}
w_in += sj4_utf16_read((const unsigned char*)w_in, &n);
n = ucs_to_euc(n);
@ -192,35 +212,55 @@ int sj4_from_utf16(u_char* out, const u_char* in, int len) {
return out - o_out;
}
#endif
static u_int eucjp_read(const u_char* in) {
int sj4_eucjp_read(const unsigned char* in, int* output) {
u_char c = *in;
u_int n = 0;
if(c <= 0x7f) {
n = c;
*output = c;
return 1;
} else if(c != 0x8f) {
n = CAST_I32(in[0]) << 8;
n |= CAST_I32(in[1]);
*output = n;
return 2;
} else {
n = CAST_I32(in[0]) << 16;
n |= CAST_I32(in[1]) << 8;
n |= CAST_I32(in[2]);
}
return n;
}
*output = n;
static int eucjp_codesize(u_int n) {
if(n <= 0xff) {
return 1;
} else if(n <= 0xffff) {
return 2;
} else {
return 3;
}
}
#endif
int sj4_sjis_read(const unsigned char* in, int* output) {
u_char c;
u_int n = 0;
c = in[0];
if(c <= 0x7f || (0xa1 <= c && c <= 0xdf)) {
*output = c;
return 1;
} else if((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xfc)) {
n = CAST_I32(in[0]) << 8;
n |= in[1];
*output = n;
return 2;
}
return 0;
}
int sj4_to_sjis(u_char* out, const u_char* in, int len) {
unsigned char d[] = {0, 0};
@ -235,10 +275,10 @@ int sj4_to_utf8(u_char* out, const u_char* in, int len) {
u_char* o_out = out;
while((in - o_in) < len) {
int i, j = 0;
u_int n = eucjp_read(in);
int i, j = 0;
int n;
in += eucjp_codesize(n);
in += sj4_eucjp_read(in, &n);
n = euc_to_ucs(n);
@ -272,10 +312,10 @@ int sj4_to_utf16(u_char* out, const u_char* in, int len) {
wchar_t* o_out = w_out;
while((in - o_in) < len) {
int i, j = 0;
u_int n = eucjp_read(in);
int i, j = 0;
int n;
in += eucjp_codesize(n);
in += sj4_eucjp_read(in, &n);
n = euc_to_ucs(n);
@ -322,3 +362,18 @@ int sj4_charset_from(int type, void* output, const void* input, int len) {
return len;
}
int sj4_charset_read(int type, int* output, const void* input) {
if(type == SJ4EUCJP) {
return sj4_eucjp_read(input, output);
} else if(type == SJ4SJIS) {
return sj4_sjis_read(input, output);
}
#ifdef UCS
else if(type == SJ4UTF8) {
return sj4_utf8_read(input, output);
} else if(type == SJ4UTF16) {
return sj4_utf16_read(input, output);
}
#endif
}