src/encode/EUCJIS2004.js
/**
* The script is part of Mojix.
*
* AUTHOR:
* natade (http://twitter.com/natadea)
*
* LICENSE:
* The MIT license https://opensource.org/licenses/MIT
*/
import SJIS from "./SJIS.js";
import SJIS2004 from "./SJIS2004.js";
/**
* EUC-JIS-2004 を扱うクラス
* @ignore
*/
export default class EUCJIS2004 {
/**
* 文字列を EUC-JIS-2004 のバイナリ配列に変換。変換できない文字は "?" に変換される。
* @param {string} text - 変換したいテキスト
* @returns {number[]} EUC-JIS-2004 のデータが入ったバイナリ配列
*/
static toEUCJIS2004Binary(text) {
const sjis_array = SJIS2004.toSJIS2004Array(text);
const bin = [];
const ng = "?".charCodeAt(0);
// prettier-ignore
const SS2 = 0x8E; // C1制御文字 シングルシフト2
// prettier-ignore
const SS3 = 0x8F; // C1制御文字 シングルシフト3
for (let i = 0; i < sjis_array.length; i++) {
const code = sjis_array[i];
const kuten = SJIS.toMenKuTenFromSJIS2004Code(code);
// prettier-ignore
if (code < 0x80) {
// G0 ASCII
bin.push(code);
// prettier-ignore
} else if (code < 0xE0) {
// G2 半角カタカナ
bin.push(SS2);
bin.push(code);
} else {
// G1 と G3 を切り替える
if (kuten.men === 2) {
// シングルシフト SS3 で G3 を呼び出す。
// G3 は JIS X 0213:2004 の2面を表す
bin.push(SS3);
}
if (kuten.ku <= 94) {
// 区点は94まで利用できる。
// つまり、最大でも 94 + 0xA0 = 0xFE となり 0xFF 以上にならない
// prettier-ignore
bin.push(kuten.ku + 0xA0);
// prettier-ignore
bin.push(kuten.ten + 0xA0);
} else {
bin.push(ng);
}
}
}
return bin;
}
/**
* EUC-JIS-2004 の配列から文字列に変換
* @param {number[]} eucjp - 変換したいテキスト
* @returns {string} 変換後のテキスト
*/
static fromEUCJIS2004Binary(eucjp) {
const sjis_array = [];
const ng = "?".charCodeAt(0);
// prettier-ignore
const SS2 = 0x8E; // C1制御文字 シングルシフト2
// prettier-ignore
const SS3 = 0x8F; // C1制御文字 シングルシフト3
for (let i = 0; i < eucjp.length; i++) {
let x1, x2;
x1 = eucjp[i];
// prettier-ignore
if (x1 < 0x80) {
// ASCII
sjis_array.push(x1);
continue;
}
if (i >= eucjp.length - 1) {
// 文字が足りない
break;
}
let men = 1;
{
if (x1 === SS3) {
// 3バイト読み込み(G3)
if (i >= eucjp.length - 2) {
// 文字が足りない
break;
}
// シングルシフト SS3 で G3 を呼び出す。
// G3 は、EUC-JIS-2000 の場合 JIS X 0213:2004 の2面を表す
men = 2;
x1 = eucjp[i + 1];
x2 = eucjp[i + 2];
i += 2;
} else {
// 2バイト読み込み
x2 = eucjp[i + 1];
i += 1;
}
}
if (x1 === SS2) {
// 半角カタカナ
sjis_array.push(x2);
continue;
}
// prettier-ignore
if (0xA1 <= x1 && x1 <= 0xFE && 0xA1 <= x2 && x2 <= 0xFE) {
// EUC-JIS-2000 JIS X 0213:2004 の2面に対応
// 日本語
// prettier-ignore
const kuten = {
men: men,
ku: x1 - 0xA0,
ten: x2 - 0xA0
};
sjis_array.push(SJIS.toSJIS2004CodeFromMenKuTen(kuten));
} else {
sjis_array.push(ng);
}
}
return SJIS2004.fromSJIS2004Array(sjis_array);
}
}