/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JCCEbcdicSinSoutAdd
*   ソースファイル名：JCCEbcdicSinSoutAdd.java
*   作成者          ：富士通
*   日付            ：2012年09月14日
*＜機能概要＞
*　EBCDICコードで作成されたファイルにシフトイン(0x0e)と
*　シフトアウト(0x0f)コードを追加する。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2012/09/14   富士通    新規作成
*   v5.00.00    2013/11/14   FJ        処理時間短縮対応
*
**********************************************************************/
package eo.common.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * EBCDICコードで作成されたファイルにシフトイン(0x0e)と
 * シフトアウト(0x0f)コードを追加する。
 * <BR>
 * @author 富士通
 */

public class JCCEbcdicSinSoutAdd {

	// 追加するシフトイン／シフトアウトコード
	private static final byte[] SIN_SOUT = {0x0e,0x0f};
	
	/**
	 * mainメソッド
	 * @param args 第一引数：変換元ファイルパス、第二引数：変換先ファイルパス、
	 *              第三引数：マルチレコード指定有無、第四引数：レコード長、
	 *              第五引数：シフトイン／シフトアウト位置
	 * @return 実施結果（0：正常終了、それ以外：エラー終了）
	 */
	private int addSf(String[] args) {

		InputStream fis = null;
		OutputStream fos = null;

		try
		{
			// パラメタ数のチェック
			if(args.length < 6)
			{
				return 1;
			}
			
			// 変換元ファイルパス
			String befFilePath = args[0];
			// 変換後ファイルパス
			String afFilePath = args[1];
			// マルチレコードバイト数
			String multiRecordPosition = args[2];
			// マルチレコード指定有無
			String multiRecord = args[3];
			// レコード長
			String lenRecord = args[4];
			// シフトイン／シフトアウト位置
			String sinoutPosition = args[5];
			
			
			// 変換元ファイルの入力ストリームを生成
			try
			{
				fis = new BufferedInputStream(new FileInputStream(new File(befFilePath)));
			}
			catch (FileNotFoundException e)
			{
				return 2;
			}
			
			// 変換先ファイルの出力ストリームを生成
			try
			{
				fos = new BufferedOutputStream(new FileOutputStream(new File(afFilePath)));
			} catch (FileNotFoundException e)
			{
				return 3;
			}

			// 変換元ファイルを読み込み、変換先ファイルへ出力
			try
			{
				// 変換元ファイルを1バイトづつ読み込み、シフトイン(0x0e)、シフトアウト(0x0f)を取り除く
				int i;
				// 1行分のバイト数カウンター
				int counter = 1;
				// シフトイン／シフトアウトの位置を配列に格納
				String[] sinoutPositionArray = sinoutPosition.split(",");
				// シフトイン／シフトアウト追加位置のカウンタ
				int sinoutCounter = 0;
				// シフトイン／シフトアウト配列のカウンタ
				int sinoutArrayCount = 0;
				// マルチレコード時のシフトイン／シフトアウト追加フラグ
				boolean sinoutFlg = true;
				while((i = fis.read()) != -1)
				{
					// 1行分のバイト数に達した際にカウンタをクリア
					if(counter > Integer.parseInt(lenRecord))
					{
						// 最終バイトに0fを書き込む。
						if(sinoutPositionArray.length > sinoutCounter)
						{
							// シフトイン／シフトアウトを追加
							fos.write(SIN_SOUT[sinoutArrayCount]);
						}
						counter = 1;
						sinoutCounter = 0;
						sinoutArrayCount = 0;
						sinoutFlg = true;
					}
					// マルチレコード時の指定バイト目のレコードをチェック
					if(counter == Integer.parseInt(multiRecordPosition) &&
							!(Integer.toHexString(i)).equals(multiRecord))
					{
						sinoutFlg = false;
					}
					// マルチレコードの判定
					if(sinoutFlg)
					{
						// 指定のバイト位置にシフトイン／シフトアウトコードを追加
						if(sinoutPositionArray.length > sinoutCounter && 
								counter == Integer.parseInt(sinoutPositionArray[sinoutCounter]))
						{
							// シフトイン／シフトアウトを追加
							fos.write(SIN_SOUT[sinoutArrayCount]);
							// シフトイン／シフトアウト配列のカウンタをカウントアップ
							sinoutCounter++;
							// シフトイン／シフトアウト配列のカウンタを切り替え
							sinoutArrayCount = (sinoutArrayCount == 0) ? 1 : 0;
						}
					}
					// 元データをファイルに書き込み
					fos.write(i);
					// 1行分のバイト数カウンタをカウントアップ
					counter++;
				}
				// 最終バイトに0fを書き込む。
				if(sinoutPositionArray.length > sinoutCounter)
				{
					// シフトイン／シフトアウトを追加
					fos.write(SIN_SOUT[sinoutArrayCount]);
				}
			}
			catch (IOException e)
			{
				return 4;
			}
			
			// 正常終了
			return 0;
		}
		finally
		{
			try
			{
				// リソースの解放
				if(fis != null)
				{
					fis.close();
				}
				if(fos != null)
				{
					fos.close();
				}
			}
			catch (IOException e)
			{
				return 5;
			}
		}
		
	}

	/**
	 * mainメソッド
	 * @param args 第一引数：変換元ファイルパス、第二引数：変換先ファイルパス、
	 *              第三引数：マルチレコード指定有無、第四引数：レコード長、
	 *              第五引数：シフトイン／シフトアウト位置
	 */
	public static void main(String[] args) {

		int rslt = (new JCCEbcdicSinSoutAdd()).addSf(args);
		if (rslt > 0) {
			System.exit(rslt);
		}

	}
}
