Home Reference Source

src/encode/EUCJIS2004.js

/**
 * The script is part of MojiJS.
 * 
 * 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 {Array<number>} EUC-JIS-2004 のデータが入ったバイナリ配列
	 */
	static toEUCJIS2004Binary(text) {
		const sjis_array = SJIS2004.toSJIS2004Array(text);
		const bin = [];
		const ng = "?".charCodeAt(0);
		const SS2 = 0x8E; // C1制御文字 シングルシフト2
		const SS3 = 0x8F; // C1制御文字 シングルシフト3
		for(let i = 0; i < sjis_array.length; i++) {
			const code = sjis_array[i];
			const kuten = SJIS.toMenKuTenFromSJIS2004Code(code);
			if(code < 0x80) {
				// G0 ASCII
				bin.push(code);
			}
			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 以上にならない
					bin.push(kuten.ku + 0xA0);
					bin.push(kuten.ten + 0xA0);
				}
				else {
					bin.push(ng);
				}
			}
		}
		return bin;
	}

	/**
	 * EUC-JIS-2004 の配列から文字列に変換
	 * @param {Array<number>} eucjp - 変換したいテキスト
	 * @returns {String} 変換後のテキスト
	 */
	static fromEUCJIS2004Binary(eucjp) {
		const sjis_array = [];
		const ng = "?".charCodeAt(0);
		const SS2 = 0x8E; // C1制御文字 シングルシフト2
		const SS3 = 0x8F; // C1制御文字 シングルシフト3
		for(let i = 0; i < eucjp.length; i++) {
			let x1, x2;
			x1 = eucjp[i];
			// ASCII
			if(x1 < 0x80) {
				sjis_array.push(x1);
				continue;
			}
			if(i >= eucjp.length - 1) {
				// 文字が足りない
				break;
			}
			let men = 1;
			{
				// 3バイト読み込み(G3)
				if(x1 === SS3) {
					// 文字が足りない
					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;
				}
				// 2バイト読み込み
				else {
					x2 = eucjp[i + 1];
					i += 1;
				}
			}
			// 半角カタカナ
			if(x1 === SS2) {
				sjis_array.push(x2);
				continue;
			}

			if((0xA1 <= x1) && (x1 <= 0xFE) && (0xA1 <= x2) && (x2 <= 0xFE)) {
				// EUC-JIS-2000 JIS X 0213:2004 の2面に対応
				// 日本語
				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);
	}

}