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

using blanco.sample.csv.record;
using blanco.sample.csv.util;

namespace blanco.sample.csv.io
{
    /// <summary>ファイル定義[BlancoCsvSampleDotNet/このクラスは単にサンプルです。実際の動作には利用されません。]のリーダクラス。</summary>
    /// <remarks>
    /// <newpara>このクラスはファイル定義書(CSV)から自動生成されたリーダクラスです。</newpara>
    /// <newpara>　1.文字列長チェックには、デフォルトエンコーディングを利用します。</newpara>
    /// <newpara>　2.クラスの利用した後は必ず Close()を呼び出してください。</newpara>
    /// </remarks>
    public class BlancoCsvSampleDotNetCsvReader
    {
        /// <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>項目[field_15]の読み込みの際に利用するフォーマッター。</summary>
        /// <remarks>
        /// <newpara>※インスタンス化しておくことによりメモリゴミ発生を抑制します。</newpara>
        /// </remarks>
        private string fSimpleDateFormatField15;

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

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

            // 項目番号[1]項目名[field_1/フィールド1]
            tokenString = BlancoCsvRuntimeUtil.ReadToken(reader, ',', false);
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 1項目目。項目番号[1] 項目名[field_1/フィールド1]の処理中において不正な終端を検知しました。");
            }
            // 任意項目。
            if (tokenString.Length == 0) {
                // 必須項目ではない文字列項目に長さ0の値が読み込まれた場合には、読み込み後の値としても長さ0の文字列とします。
                record.SetField1(tokenString);
            } else {
                if (BlancoCsvRuntimeUtil.GetBytes(tokenString).Length < 1) {
                    throw new BlancoCsvIOException("入力" + fLineCounter + "行目 1項目目。項目番号[1] 項目名[field_1/フィールド1]の処理中においてMIN長さ(1)よりも短い値[" + tokenString + "]を検知しました。");
                }
                if (BlancoCsvRuntimeUtil.GetBytes(tokenString).Length > 10) {
                    throw new BlancoCsvIOException("入力" + fLineCounter + "行目 1項目目。項目番号[1] 項目名[field_1/フィールド1]の処理中においてMAX長さ(10)よりも長い値[" + tokenString + "]を検知しました。");
                }
                record.SetField1(tokenString);
            }

            // 項目番号[2]項目名[field_2/フィールド2]
            // クオートを考慮した読み込みを行います。
            tokenString = BlancoCsvRuntimeUtil.ReadTokenWithQuote(reader, ',');
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 2項目目。項目番号[2] 項目名[field_2/フィールド2]の処理中において不正な終端を検知しました。");
            }
            // 任意項目。
            if (tokenString.Length == 0) {
                // 必須項目ではない文字列項目に長さ0の値が読み込まれた場合には、読み込み後の値としても長さ0の文字列とします。
                record.SetField2(tokenString);
            } else {
                if (BlancoCsvRuntimeUtil.GetBytes(tokenString).Length < 4) {
                    throw new BlancoCsvIOException("入力" + fLineCounter + "行目 2項目目。項目番号[2] 項目名[field_2/フィールド2]の処理中においてMIN長さ(4)よりも短い値[" + tokenString + "]を検知しました。");
                }
                if (BlancoCsvRuntimeUtil.GetBytes(tokenString).Length > 4) {
                    throw new BlancoCsvIOException("入力" + fLineCounter + "行目 2項目目。項目番号[2] 項目名[field_2/フィールド2]の処理中においてMAX長さ(4)よりも長い値[" + tokenString + "]を検知しました。");
                }
                record.SetField2(tokenString);
            }

            // 項目番号[3]項目名[field_3/フィールド3]
            tokenString = BlancoCsvRuntimeUtil.ReadToken(reader, ',', false);
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 3項目目。項目番号[3] 項目名[field_3/フィールド3]の処理中において不正な終端を検知しました。");
            }
            // 任意項目。
            if (tokenString.Length == 0) {
                // 必須項目ではない項目に長さ0の値が読み込まれた場合には、値としての代入は行いません。
                record.SetField3(int.MinValue);
            } else {
                try {
                    record.SetField3(Int32.Parse(tokenString));
                } catch (FormatException ex) {
                    throw new BlancoCsvIOException("入力" + fLineCounter + "行目 3項目目。項目番号[3] 項目名[field_3/フィールド3]の処理中において数値(int)としては解析できない文字[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
                }
            }

            // 項目番号[4]項目名[field_4/フィールド4]
            tokenString = BlancoCsvRuntimeUtil.ReadToken(reader, ',', false);
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 4項目目。項目番号[4] 項目名[field_4/フィールド4]の処理中において不正な終端を検知しました。");
            }
            // 任意項目。
            if (tokenString.Length == 0) {
                // 必須項目ではない項目に長さ0の値が読み込まれた場合には、値としての代入は行いません。
                record.SetField4(long.MinValue);
            } else {
                try {
                    record.SetField4(Int64.Parse(tokenString));
                } catch (FormatException ex) {
                    throw new BlancoCsvIOException("入力" + fLineCounter + "行目 4項目目。項目番号[4] 項目名[field_4/フィールド4]の処理中において数値(long)としては解析できない文字[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
                }
            }

            // 項目番号[5]項目名[field_5/フィールド5]
            tokenString = BlancoCsvRuntimeUtil.ReadToken(reader, ',', false);
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 5項目目。項目番号[5] 項目名[field_5/フィールド5]の処理中において不正な終端を検知しました。");
            }
            // 任意項目。
            if (tokenString.Length == 0) {
                // 必須項目ではない項目に長さ0の値が読み込まれた場合には、値としての代入は行いません。
                record.SetField5(System.DateTime.MinValue);
            } else {
                try {
                    record.SetField5(DateTime.ParseExact(tokenString, fSimpleDateFormatField5, null));
                } catch (FormatException ex) {
                    throw new BlancoCsvIOException("入力" + fLineCounter + "行目 5項目目。項目番号[5] 項目名[field_5/フィールド5]の処理中において与えられた形式[" + fSimpleDateFormatField5 + "]では解析できない文字列[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
                }
            }

            // 項目番号[6]項目名[field_6/フィールド6]
            tokenString = BlancoCsvRuntimeUtil.ReadToken(reader, ',', false);
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 6項目目。項目番号[6] 項目名[field_6/フィールド6]の処理中において不正な終端を検知しました。");
            }
            // 任意項目。
            if (tokenString.Length == 0) {
                // 必須項目ではない項目に長さ0の値が読み込まれた場合には、値としての代入は行いません。
                record.SetField6(decimal.MinValue);
            } else {
                try {
                    record.SetField6(Convert.ToDecimal(tokenString));
                } catch (FormatException ex) {
                    throw new BlancoCsvIOException("入力" + fLineCounter + "行目 6項目目。項目番号[6] 項目名[field_6/フィールド6]の処理中において数値(decimal)としては解析できない文字[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
                }
            }

            // 項目番号[7]項目名[field_11/フィールド11]
            tokenString = BlancoCsvRuntimeUtil.ReadToken(reader, ',', false);
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 7項目目。項目番号[7] 項目名[field_11/フィールド11]の処理中において不正な終端を検知しました。");
            }
            // 必須項目。
            if (tokenString.Length == 0) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 7項目目。項目番号[7] 項目名[field_11/フィールド11]の処理中において必須項目に値が入っていないことを検知しました。");
            }
            if (BlancoCsvRuntimeUtil.GetBytes(tokenString).Length < 1) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 7項目目。項目番号[7] 項目名[field_11/フィールド11]の処理中においてMIN長さ(1)よりも短い値[" + tokenString + "]を検知しました。");
            }
            if (BlancoCsvRuntimeUtil.GetBytes(tokenString).Length > 10) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 7項目目。項目番号[7] 項目名[field_11/フィールド11]の処理中においてMAX長さ(10)よりも長い値[" + tokenString + "]を検知しました。");
            }
            record.SetField11(tokenString);

            // 項目番号[8]項目名[field_12/フィールド12]
            // クオートを考慮した読み込みを行います。
            tokenString = BlancoCsvRuntimeUtil.ReadTokenWithQuote(reader, ',');
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 8項目目。項目番号[8] 項目名[field_12/フィールド12]の処理中において不正な終端を検知しました。");
            }
            // 必須項目。
            if (tokenString.Length == 0) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 8項目目。項目番号[8] 項目名[field_12/フィールド12]の処理中において必須項目に値が入っていないことを検知しました。");
            }
            if (BlancoCsvRuntimeUtil.GetBytes(tokenString).Length < 4) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 8項目目。項目番号[8] 項目名[field_12/フィールド12]の処理中においてMIN長さ(4)よりも短い値[" + tokenString + "]を検知しました。");
            }
            if (BlancoCsvRuntimeUtil.GetBytes(tokenString).Length > 4) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 8項目目。項目番号[8] 項目名[field_12/フィールド12]の処理中においてMAX長さ(4)よりも長い値[" + tokenString + "]を検知しました。");
            }
            record.SetField12(tokenString);

            // 項目番号[9]項目名[field_13/フィールド13]
            tokenString = BlancoCsvRuntimeUtil.ReadToken(reader, ',', false);
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 9項目目。項目番号[9] 項目名[field_13/フィールド13]の処理中において不正な終端を検知しました。");
            }
            // 必須項目。
            if (tokenString.Length == 0) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 9項目目。項目番号[9] 項目名[field_13/フィールド13]の処理中において必須項目に値が入っていないことを検知しました。");
            }
            try {
                record.SetField13(Int32.Parse(tokenString));
            } catch (FormatException ex) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 9項目目。項目番号[9] 項目名[field_13/フィールド13]の処理中において数値(int)としては解析できない文字[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
            }

            // 項目番号[10]項目名[field_14/フィールド14]
            tokenString = BlancoCsvRuntimeUtil.ReadToken(reader, ',', false);
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 10項目目。項目番号[10] 項目名[field_14/フィールド14]の処理中において不正な終端を検知しました。");
            }
            // 必須項目。
            if (tokenString.Length == 0) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 10項目目。項目番号[10] 項目名[field_14/フィールド14]の処理中において必須項目に値が入っていないことを検知しました。");
            }
            try {
                record.SetField14(Int64.Parse(tokenString));
            } catch (FormatException ex) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 10項目目。項目番号[10] 項目名[field_14/フィールド14]の処理中において数値(long)としては解析できない文字[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
            }

            // 項目番号[11]項目名[field_15/フィールド15]
            tokenString = BlancoCsvRuntimeUtil.ReadToken(reader, ',', false);
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 11項目目。項目番号[11] 項目名[field_15/フィールド15]の処理中において不正な終端を検知しました。");
            }
            // 必須項目。
            if (tokenString.Length == 0) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 11項目目。項目番号[11] 項目名[field_15/フィールド15]の処理中において必須項目に値が入っていないことを検知しました。");
            }
            try {
                record.SetField15(DateTime.ParseExact(tokenString, fSimpleDateFormatField15, null));
            } catch (FormatException ex) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 11項目目。項目番号[11] 項目名[field_15/フィールド15]の処理中において与えられた形式[" + fSimpleDateFormatField15 + "]では解析できない文字列[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
            }

            // 項目番号[12]項目名[field_16/フィールド16]
            tokenString = BlancoCsvRuntimeUtil.ReadToken(reader, ',', true);
            if (tokenString == null) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 12項目目。項目番号[12] 項目名[field_16/フィールド16]の処理中において不正な終端を検知しました。");
            }
            // 必須項目。
            if (tokenString.Length == 0) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 12項目目。項目番号[12] 項目名[field_16/フィールド16]の処理中において必須項目に値が入っていないことを検知しました。");
            }
            try {
                record.SetField16(Convert.ToDecimal(tokenString));
            } catch (FormatException ex) {
                throw new BlancoCsvIOException("入力" + fLineCounter + "行目 12項目目。項目番号[12] 項目名[field_16/フィールド16]の処理中において数値(decimal)としては解析できない文字[" + tokenString + "]を検知しました。:" + ex.ToString(), ex);
            }
            return record;
        }

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

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