// This code is generated by blanco Framework.
// <summary>blancoFixedLengthで利用する実行時ユーティリティクラス</summary>
using System;
using System.IO;
using System.Text;

using blanco.sample.fixedlength.io;

namespace blanco.sample.fixedlength.util
{
    /// <summary>blancoFixedLengthで利用する実行時ユーティリティクラス</summary>
    /// <remarks>
    /// <newpara>このファイルはblanco Frameworkにより自動生成されています。</newpara>
    /// </remarks>
    public class BlancoFixedLengthRuntimeUtil
    {
        /// <summary>与えられたReaderから 指定の長さの固定長トークンを取り出します</summary>
        /// <param name="argReader">与えられたリーダ</param>
        /// <param name="argTokenLength">読み込みを期待するトークンの長さ。</param>
        /// <returns>取り出された固定長トークン。状況によっては期待する長さとは異なる長さの文字列が戻されます。</returns>
        public static string ReadToken(TextReader argReader, int argTokenLength)
        {
            if (argReader == null) {
                throw new ArgumentException("ReadTokenメソッドの入力パラメータのリーダにnullが与えられました。");
            }
            if (argTokenLength <= 0) {
                throw new ArgumentException("readTokenメソッドの長さとして0以下が与えられました。1以上の値を与えてください。");
            }

            StringBuilder buffer = new StringBuilder();
            for (;;) {
                int iRead = argReader.Read();
                if (iRead < 0) {
                    // 終端に到達しました。処理中断します。
                    break;
                } else {
                    buffer.Append((char) iRead);
                }

                byte[] bytesLengthCheck = null;

                bytesLengthCheck = GetBytes(buffer.ToString());

                if (bytesLengthCheck.Length >= argTokenLength) {
                    // 固定長トークンが期待する長さに到達または期待する長さを超えました。
                    // 処理中断します。
                    break;
                }
            }
            return buffer.ToString();
        }

        /// <summary>与えられた文字列を指定の長さまで右側をパディングします。</summary>
        /// <param name="argSource">入力文字列。</param>
        /// <param name="argLength">目標とするトータルバイト長。</param>
        /// <param name="argPadChar">埋める際に利用するパディング文字。</param>
        /// <returns>目標となるバイト長に加工された後の文字列。</returns>
        public static string PadRight(string argSource, int argLength, char argPadChar)
        {
            if (argSource == null) {
                throw new ArgumentException("PadRightの入力文字列に nullが与えられました。");
            }

            string result = argSource;
            for (;;) {
                if (GetBytesLength(result) >= argLength) {
                    break;
                }

                // 一文字ずつ増やしていきます。
                result = result + argPadChar;
            }
            return result;
        }

        /// <summary>与えられた文字列を指定の長さまで左側をパディングします。</summary>
        /// <param name="argSource">入力文字列。</param>
        /// <param name="argLength">目標とするトータルバイト長。</param>
        /// <param name="argPadChar">埋める際に利用するパディング文字。</param>
        /// <returns>目標となるバイト長に加工された後の文字列。</returns>
        public static string PadLeft(string argSource, int argLength, char argPadChar)
        {
            if (argSource == null) {
                throw new ArgumentException("PadLeftの入力文字列に nullが与えられました。");
            }

            string result = argSource;
            for (;;) {
                if (GetBytesLength(result) >= argLength) {
                    break;
                }

                // 一文字ずつ増やしていきます。
                result = argPadChar + result;
            }
            return result;
        }

        /// <summary>与えられた文字列のバイト長を取得します。</summary>
        /// <param name="argSource">入力文字列。</param>
        /// <returns>入力文字列のバイト長。</returns>
        private static int GetBytesLength(string argSource)
        {
            if (argSource == null) {
                throw new ArgumentException("GetBytesLengthの入力文字列に nullが与えられました。");
            }
            return GetBytes(argSource).Length;
        }

        /// <summary>文字列をバイト配列に変換します。</summary>
        /// <param name="inputString">変換元の文字列。</param>
        /// <returns>バイト配列に変換後の文字列。</returns>
        public static byte[] GetBytes(string inputString)
        {
            if (inputString == null)
            {
                throw new ArgumentException("GetBytesメソッドにnullが与えられました。");
            }
            // 文字列をバイト配列に変換します。
            byte[] inputBytes = Encoding.Unicode.GetBytes(inputString);
            // エンコーディングを取得します。ここではシフトJISへのエンコーディングを取得しています。
            //TODO: 定義書で指定されているエンコードをする必要があります。
            Encoding targetEncoding = Encoding.GetEncoding(932);
            // 実際にコードを変換。
            return Encoding.Convert(Encoding.Unicode, targetEncoding, inputBytes);
        }
    }
}
