package org.phosphoresce.commons.util;

import java.io.IOException;
import java.io.StringReader;

import sun.io.CharToByteConverter;

/**
 * native2asciiユーティリティクラス<br>
 *
 * @author Kitagawa<br>
 *
 *<!--
 * 更新日		更新者			更新内容
 * 2008/05/21	Kitagawa		新規作成
 *-->
 */
public final class Native2AsciiUtil {

	/** ラインセパレータ */
	public static final String SEPARATOR = System.getProperty("line.separator");

	/** ディフォルトエンコード */
	public static final String DEFALUT_ENCODE = "MS932";

	/**
	 * コンストラクタ<br>
	 */
	private Native2AsciiUtil() {
		super();
	}

	/**
	 * ネイティブ文字列からアスキー変換を行った文字列として提供します。<br>
	 * @param value 変換対象文字列
	 * @return 変換後文字列
	 */
	public static String native2ascii(String value) {
		StringBuffer result = new StringBuffer();
		char[] chars = value.toCharArray();
		for (int i = 0; i <= chars.length - 1; i++) {
			if (chars[i] > '\177') {
				result.append((char) 92);
				result.append((char) 117);
				String hex = Integer.toHexString(chars[i]);
				StringBuffer buffer = new StringBuffer(hex);
				buffer.reverse();
				int l = 4 - buffer.length();
				for (int i1 = 0; i1 < l; i1++) {
					buffer.append('0');
				}
				for (int j1 = 0; j1 < 4; j1++) {
					result.append(buffer.charAt(3 - j1));
				}

			} else {
				result.append(chars[i]);
			}
		}
		return result.toString();
	}

	/**
	 * 指定されたアスキー文字列をネイティブ文字列に変換して提供します。<br>
	 * @param value 変換対象文字列
	 * @param encode 変換時文字コード
	 * @return 変換後文字列
	 * @throws IOException 変換時文字コードによるコンバータオブジェクトの生成に失敗した場合にスローされます
	 */
	public static String ascii2native(String value, String encode) throws IOException {
		CharToByteConverter converter = CharToByteConverter.getConverter(encode);

		char[] sourceChars = value.toCharArray();
		char[] trailChars = null;
		StringReader in = new StringReader(value);

		int k = 0;
		int l = 0;
		char ac1[] = new char[sourceChars.length];
		boolean flag = false;
		boolean flag1 = false;
		if (trailChars != null) {
			for (int i1 = 0; i1 < trailChars.length; i1++)
				ac1[i1] = trailChars[i1];

			k = trailChars.length;
			trailChars = null;
		}
		int j1 = in.read(ac1, k, sourceChars.length - k);
		if (j1 < 0) {
			flag1 = true;
			if (k == 0)
				return "";
		} else {
			k += j1;
		}
		int k1 = 0;
		do {
			if (k1 >= k)
				break;
			char c = ac1[k1++];
			if (c != '\\' || flag1 && k <= 5) {
				sourceChars[l++] = c;
				continue;
			}
			int l1 = k - k1;
			if (l1 < 5) {
				trailChars = new char[1 + l1];
				trailChars[0] = c;
				for (int i2 = 0; i2 < l1; i2++)
					trailChars[1 + i2] = ac1[k1 + i2];

				break;
			}
			c = ac1[k1++];
			if (c != 'u') {
				sourceChars[l++] = '\\';
				sourceChars[l++] = c;
			} else {
				char c1 = (char) Integer.parseInt(new String(ac1, k1, 4), 16);
				if (converter.canConvert(c1)) {
					sourceChars[l++] = c1;
					k1 += 4;
				} else {
					sourceChars[l++] = '\\';
					sourceChars[l++] = 'u';
				}
			}
		} while (true);

		return new String(sourceChars, 0, l);
	}

	/**
	 * 指定されたアスキー文字列をネイティブ文字列に変換して提供します。<br>
	 * 変換時の文字コードはディフォルトのMS932が使用されます。<br>
	 * @param value 変換対象文字列
	 * @return 変換後文字列
	 * @throws IOException 変換時文字コードによるコンバータオブジェクトの生成に失敗した場合にスローされます
	 */
	public static String ascii2native(String value) throws IOException {
		return ascii2native(value, DEFALUT_ENCODE);
	}
}

