// This code is generated by blanco Framework.
// <summary>ファイル定義書(固定長)から作成されたリーダクラス</summary>
using System;
using System.IO;

using blanco.sample.fixedlength.record;
using blanco.sample.fixedlength.util;

namespace blanco.sample.fixedlength.io
{
    /// <summary>ファイル定義[SAMPLE_FIXED_LENGTH/固定長ファイルのサンプル。このクラスは単にサンプルです。実際の動作には利用されません。]のリーダクラス</summary>
    /// <remarks>
    /// <newpara>このクラスはファイル定義書(固定長)から自動生成されたリーダクラスです。</newpara>
    /// <newpara>　1.文字列長チェックには、デフォルトエンコーディングを利用します。</newpara>
    /// <newpara>　2.クラスの利用した後は必ず Close()を呼び出してください。</newpara>
    /// </remarks>
    public class SampleFixedLengthFixedLengthReader
    {
        /// <summary>リーダオブジェクト</summary>
        /// <remarks>
        /// <newpara>内部的に実際に入力を行うのリーダを記憶します。</newpara>
        /// </remarks>
        private TextReader fReader;

        /// <summary>処理中の行カウンタ</summary>
        /// <remarks>
        /// <newpara>現在処理を行っている行の位置を記憶します。</newpara>
        /// </remarks>
        private long fLineCounter = 0;

        /// <summary>項目[field_5]の読み込みの際に利用するフォーマッター</summary>
        /// <remarks>
        /// <newpara>※インスタンス化しておくことによりメモリゴミ発生を抑制します。</newpara>
        /// </remarks>
        private string fSimpleDateFormatField5;

        /// <summary>固定長ファイルリーダクラスのコンストラクタ</summary>
        /// <remarks>
        /// <newpara>与えられたリーダと連結します。</newpara>
        /// </remarks>
        /// <param name="arg">連結するリーダ</param>
        public SampleFixedLengthFixedLengthReader(TextReader arg)
        {
            fReader = arg;
            fSimpleDateFormatField5 = "yyyy/MM/dd HH:mm:ss";
        }

        /// <summary>次の一行を読み込みます</summary>
        /// <returns>行オブジェクトを返します。もはや行が無い場合には nullを返します。</returns>
        public SampleFixedLengthFixedLengthRecord ReadRecord()
        {
            string line = fReader.ReadLine();
            if (line == null) {
                // ファイルの終端に到達しました。
                return null;
            }
            fLineCounter++;
            SampleFixedLengthFixedLengthRecord record = new SampleFixedLengthFixedLengthRecord();
            StringReader reader = new StringReader(line);
            string tokenString = null;

            // 項目番号[1]項目名[field_1/フィールド1]
            tokenString = BlancoFixedLengthRuntimeUtil.ReadToken(reader, 10);
            if (BlancoFixedLengthRuntimeUtil.GetBytes(tokenString).Length < 10) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 1項目目。項目番号[1] 項目名[field_1/フィールド1]の処理中において長さ(10)よりも短い値[" + tokenString + "]を検知しました。");
            }
            if (BlancoFixedLengthRuntimeUtil.GetBytes(tokenString).Length > 10) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 1項目目。項目番号[1] 項目名[field_1/フィールド1]の処理中において長さ(10)よりも長い値[" + tokenString + "]を検知しました。");
            }
            record.SetField1(tokenString);

            // 項目番号[2]項目名[field_2/フィールド2]
            tokenString = BlancoFixedLengthRuntimeUtil.ReadToken(reader, 9);
            if (BlancoFixedLengthRuntimeUtil.GetBytes(tokenString).Length < 9) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 2項目目。項目番号[2] 項目名[field_2/フィールド2]の処理中において長さ(9)よりも短い値[" + tokenString + "]を検知しました。");
            }
            if (BlancoFixedLengthRuntimeUtil.GetBytes(tokenString).Length > 9) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 2項目目。項目番号[2] 項目名[field_2/フィールド2]の処理中において長さ(9)よりも長い値[" + tokenString + "]を検知しました。");
            }
            try {
                record.SetField2(Int32.Parse(tokenString.Trim()));
            } catch (FormatException ex) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 2項目目。項目番号[2] 項目名[field_2/フィールド2]の処理中において数値(int)としては解析できない文字[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
            }

            // 項目番号[3]項目名[field_3/フィールド3]
            tokenString = BlancoFixedLengthRuntimeUtil.ReadToken(reader, 10);
            if (BlancoFixedLengthRuntimeUtil.GetBytes(tokenString).Length < 10) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 3項目目。項目番号[3] 項目名[field_3/フィールド3]の処理中において長さ(10)よりも短い値[" + tokenString + "]を検知しました。");
            }
            if (BlancoFixedLengthRuntimeUtil.GetBytes(tokenString).Length > 10) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 3項目目。項目番号[3] 項目名[field_3/フィールド3]の処理中において長さ(10)よりも長い値[" + tokenString + "]を検知しました。");
            }
            try {
                record.SetField3(Int64.Parse(tokenString.Trim()));
            } catch (FormatException ex) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 3項目目。項目番号[3] 項目名[field_3/フィールド3]の処理中において数値(long)としては解析できない文字[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
            }

            // 項目番号[4]項目名[field_4/フィールド4]
            tokenString = BlancoFixedLengthRuntimeUtil.ReadToken(reader, 7);
            if (BlancoFixedLengthRuntimeUtil.GetBytes(tokenString).Length < 7) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 4項目目。項目番号[4] 項目名[field_4/フィールド4]の処理中において長さ(7)よりも短い値[" + tokenString + "]を検知しました。");
            }
            if (BlancoFixedLengthRuntimeUtil.GetBytes(tokenString).Length > 7) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 4項目目。項目番号[4] 項目名[field_4/フィールド4]の処理中において長さ(7)よりも長い値[" + tokenString + "]を検知しました。");
            }
            try {
                record.SetField4(Convert.ToDecimal(tokenString.Trim()));
            } catch (FormatException ex) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 4項目目。項目番号[4] 項目名[field_4/フィールド4]の処理中において数値(decimal)としては解析できない文字[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
            }

            // 項目番号[5]項目名[field_5/フィールド5]
            tokenString = BlancoFixedLengthRuntimeUtil.ReadToken(reader, 19);
            if (BlancoFixedLengthRuntimeUtil.GetBytes(tokenString).Length < 19) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 5項目目。項目番号[5] 項目名[field_5/フィールド5]の処理中において長さ(19)よりも短い値[" + tokenString + "]を検知しました。");
            }
            if (BlancoFixedLengthRuntimeUtil.GetBytes(tokenString).Length > 19) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 5項目目。項目番号[5] 項目名[field_5/フィールド5]の処理中において長さ(19)よりも長い値[" + tokenString + "]を検知しました。");
            }
            try {
                record.SetField5(DateTime.ParseExact(tokenString.Trim(), fSimpleDateFormatField5, null));
            } catch (FormatException ex) {
                throw new BlancoFixedLengthIOException("入力" + fLineCounter + "行目 5項目目。項目番号[5] 項目名[field_5/フィールド5]の処理中において与えられた形式[" + fSimpleDateFormatField5 + "]では解析できない文字列[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
            }

            if (reader.Read() >= 0) {
                throw new BlancoFixedLengthIOException("全ての列の固定長データを超えるデータが行に存在することを検知しました。");
            }
            return record;
        }

        /// <summary>現在処理中の行カウンタを返します。</summary>
        /// <returns>現在処理中の行カウンタ。</returns>
        public long GetLineCounter()
        {
            return fLineCounter;
        }

        /// <summary>このリーダを閉じます。</summary>
        /// <remarks>
        /// <newpara>関連づけられていたリーダに対してもClose()を呼び出します。</newpara>
        /// </remarks>
        public void Close()
        {
            fReader.Close();
        }
    }
}
