📄 nls_euc-jp.c
字号:
}
}
/* EUC to SJIS IBM extended characters (G3 JIS X 0212 block) */
static inline int euc2sjisibm_jisx0212(unsigned char *sjis, const unsigned char euc_hi,
const unsigned char euc_lo)
{
int index, min_index, max_index;
unsigned short euc;
min_index = 0;
max_index = MAP_ELEMENT_OF(euc2sjisibm_jisx0212_map) - 1;
euc = (euc_hi << 8) | euc_lo;
while (min_index <= max_index) {
index = (min_index + max_index) / 2;
if (euc < euc2sjisibm_jisx0212_map[index].euc)
max_index = index - 1;
else
min_index = index + 1;
if (euc == euc2sjisibm_jisx0212_map[index].euc) {
sjis[0] = euc2sjisibm_jisx0212_map[index].sjis[0];
sjis[1] = euc2sjisibm_jisx0212_map[index].sjis[1];
return 3;
}
}
return 0;
}
/* EUC to SJIS IBM extended characters (G3 Upper block) */
static inline int euc2sjisibm_g3upper(unsigned char *sjis, const unsigned char euc_hi,
const unsigned char euc_lo)
{
int index;
if (euc_hi == 0xF3)
index = ((euc_hi << 8) | euc_lo) - 0xF3F3;
else
index = ((euc_hi << 8) | euc_lo) - 0xF4A1 + 12;
if ((index < 0) || (index >= MAP_ELEMENT_OF(euc2sjisibm_g3upper_map)))
return 0;
sjis[0] = euc2sjisibm_g3upper_map[index][0];
sjis[1] = euc2sjisibm_g3upper_map[index][1];
return 3;
}
/* EUC to SJIS IBM extended characters (G3 block) */
static inline int euc2sjisibm(unsigned char *sjis, const unsigned char euc_hi,
const unsigned char euc_lo)
{
int n;
#if 0
if ((euc_hi == 0xA2) && (euc_lo == 0xCC)) {
sjis[0] = 0xFA;
sjis[1] = 0x54;
return 2;
} else if ((euc_hi == 0xA2) && (euc_lo == 0xE8)) {
sjis[0] = 0xFA;
sjis[1] = 0x5B;
return 2;
}
#endif
if ((n = euc2sjisibm_g3upper(sjis, euc_hi, euc_lo))) {
return n;
} else if ((n = euc2sjisibm_jisx0212(sjis, euc_hi, euc_lo))) {
return n;
}
return 0;
}
/* NEC/IBM extended characters to IBM extended characters */
static inline int sjisnec2sjisibm(unsigned char *sjisibm,
const unsigned char sjisnec_hi,
const unsigned char sjisnec_lo)
{
int count;
if (! IS_SJIS_NECIBM(sjisnec_hi, sjisnec_lo))
return 0;
if ((sjisnec_hi == 0xEE) && (sjisnec_lo == 0xF9)) {
sjisibm[0] = 0x81;
sjisibm[1] = 0xCA;
return 2;
}
if ((sjisnec_hi == 0xEE) && (sjisnec_lo >= 0xEF)) {
count = (sjisnec_hi << 8 | sjisnec_lo)
- (sjisnec_lo <= 0xF9 ? 0xEEEF : (0xEEEF - 10));
} else {
count = (sjisnec_hi - 0xED) * (0xFC - 0x40)
+ (sjisnec_lo - 0x40) + (0x5C - 0x40);
if (sjisnec_lo >= 0x7F)
count--;
}
sjisibm[0] = 0xFA + (count / (0xFC - 0x40));
sjisibm[1] = 0x40 + (count % (0xFC - 0x40));
if (sjisibm[1] >= 0x7F)
sjisibm[1]++;
return 2;
}
static int uni2char(const wchar_t uni,
unsigned char *out, int boundlen)
{
int n;
if (!p_nls)
return -EINVAL;
if ((n = p_nls->uni2char(uni, out, boundlen)) < 0)
return n;
/* translate SJIS into EUC-JP */
if (n == 1) {
if (IS_SJIS_JISX0201KANA(out[0])) {
/* JIS X 0201 KANA */
if (boundlen < 2)
return -ENAMETOOLONG;
out[1] = out[0];
out[0] = SS2;
return 2;
}
} else if (n == 2) {
/* NEC/IBM extended characters to IBM extended characters */
sjisnec2sjisibm(out, out[0], out[1]);
if (IS_SJIS_UDC_LOW(out[0], out[1])) {
/* User defined characters half low */
MAP_SJIS2EUC(out[0], out[1], 0xF0, out[0], out[1], 0xF5);
} else if (IS_SJIS_UDC_HI(out[0], out[1])) {
/* User defined characters half high */
unsigned char ch, cl;
if (boundlen < 3)
return -ENAMETOOLONG;
n = 3; ch = out[0]; cl = out[1];
out[0] = SS3;
MAP_SJIS2EUC(ch, cl, 0xF5, out[1], out[2], 0xF5);
} else if (IS_SJIS_IBM(out[0], out[1])) {
/* IBM extended characters */
unsigned char euc[3], i;
n = sjisibm2euc(euc, out[0], out[1]);
if (boundlen < n)
return -ENAMETOOLONG;
for (i = 0; i < n; i++)
out[i] = euc[i];
} else if (IS_SJIS_JISX0208(out[0], out[1])) {
/* JIS X 0208 (include NEC special characters) */
out[0] = (out[0]^0xA0)*2 + 0x5F;
if (out[1] > 0x9E)
out[0]++;
if (out[1] < 0x7F)
out[1] = out[1] + 0x61;
else if (out[1] < 0x9F)
out[1] = out[1] + 0x60;
else
out[1] = out[1] + 0x02;
} else {
/* Invalid characters */
return -EINVAL;
}
}
else
return -EINVAL;
return n;
}
static int char2uni(const unsigned char *rawstring, int boundlen,
wchar_t *uni)
{
unsigned char sjis_temp[2];
int euc_offset, n;
if ( !p_nls )
return -EINVAL;
if (boundlen <= 0)
return -ENAMETOOLONG;
/* translate EUC-JP into SJIS */
if (rawstring[0] > 0x7F) {
if (rawstring[0] == SS3) {
if (boundlen < 3)
return -EINVAL;
euc_offset = 3;
if (IS_EUC_UDC_HI(rawstring[1], rawstring[2])) {
/* User defined characters half high */
MAP_EUC2SJIS(rawstring[1], rawstring[2], 0xF5,
sjis_temp[0], sjis_temp[1], 0xF5);
} else if (euc2sjisibm(sjis_temp,rawstring[1],rawstring[2])) {
/* IBM extended characters */
} else {
/* JIS X 0212 and Invalid characters*/
return -EINVAL;
/* 'GETA' with SJIS coding */
/* sjis_temp[0] = 0x81; */
/* sjis_temp[1] = 0xAC; */
}
} else {
if (boundlen < 2)
return -EINVAL;
euc_offset = 2;
if (IS_EUC_JISX0201KANA(rawstring[0], rawstring[1])) {
/* JIS X 0201 KANA */
sjis_temp[0] = rawstring[1];
sjis_temp[1] = 0x00;
} else if (IS_EUC_UDC_LOW(rawstring[0], rawstring[1])) {
/* User defined characters half low */
MAP_EUC2SJIS(rawstring[0], rawstring[1], 0xF5,
sjis_temp[0], sjis_temp[1], 0xF0);
} else if (IS_EUC_JISX0208(rawstring[0], rawstring[1])) {
/* JIS X 0208 (include NEC spesial characters) */
sjis_temp[0] = ((rawstring[0]-0x5f)/2) ^ 0xA0;
if (!(rawstring[0] & 1))
sjis_temp[1] = rawstring[1] - 0x02;
else if (rawstring[1] < 0xE0)
sjis_temp[1] = rawstring[1] - 0x61;
else
sjis_temp[1] = rawstring[1] - 0x60;
} else {
/* Invalid characters */
return -EINVAL;
}
}
} else {
euc_offset = 1;
/* JIS X 0201 ROMAJI */
sjis_temp[0] = rawstring[0];
sjis_temp[1] = 0x00;
}
if ( (n = p_nls->char2uni(sjis_temp, sizeof(sjis_temp), uni)) < 0)
return n;
return euc_offset;
}
static struct nls_table table = {
"euc-jp",
uni2char,
char2uni,
NULL,
NULL,
THIS_MODULE,
};
static int __init init_nls_euc_jp(void)
{
p_nls = load_nls("cp932");
if (p_nls) {
table.charset2upper = p_nls->charset2upper;
table.charset2lower = p_nls->charset2lower;
return register_nls(&table);
}
return -EINVAL;
}
static void __exit exit_nls_euc_jp(void)
{
unregister_nls(&table);
unload_nls(p_nls);
}
module_init(init_nls_euc_jp)
module_exit(exit_nls_euc_jp)
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
*
---------------------------------------------------------------------------
* Local variables:
* c-indent-level: 8
* c-brace-imaginary-offset: 0
* c-brace-offset: -8
* c-argdecl-indent: 8
* c-label-offset: -8
* c-continued-statement-offset: 8
* c-continued-brace-offset: 0
* End:
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -