/*
 * This code is generated by blanco Framework.
 * blancoFixedLengthで利用する実行時ユーティリティクラス<br>
 */
package blanco.sample.fixedlength.util;

import java.io.IOException;
import java.io.Reader;
import java.io.UnsupportedEncodingException;

import blanco.sample.fixedlength.io.BlancoFixedLengthIOException;

/**
 * blancoFixedLengthで利用する実行時ユーティリティクラス<br>
 * このファイルはblanco Frameworkにより自動生成されています。
 */
public class BlancoFixedLengthRuntimeUtil {
    /**
     * 与えられたReaderから 指定の長さの固定長トークンを取り出します
     *
     * @param argReader 与えられたリーダ
     * @param argTokenLength 読み込みを期待するトークンの長さ。
     * @param argEncoding 文字列のエンコーディング。
     * @return 取り出された固定長トークン。状況によっては期待する長さとは異なる長さの文字列が戻されます。
     * @throws BlancoFixedLengthIOException 項目数が足りないなど与えられた文字列に関する例外が発生した場合。
     * @throws IOException 入出力例外が発生した場合。
     */
    public static String readToken(final Reader argReader, final int argTokenLength, final String argEncoding) throws BlancoFixedLengthIOException, IOException {
        if (argReader == null) {
            throw new IllegalArgumentException("readTokenメソッドの入力パラメータのリーダにnullが与えられました。");
        }
        if (argTokenLength <= 0) {
            throw new IllegalArgumentException("readTokenメソッドの長さとして0以下が与えられました。1以上の値を与えてください。");
        }

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

            byte[] bytesLengthCheck = null;
            if (argEncoding == null) {
                bytesLengthCheck = buffer.toString().getBytes();
            } else {
                bytesLengthCheck = buffer.toString().getBytes(argEncoding);
            }

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

    /**
     * 与えられた文字列を指定の長さまで右側をパディングします。
     *
     * @param argSource 入力文字列。
     * @param argLength 目標とするトータルバイト長。
     * @param argPadChar 埋める際に利用するパディング文字。
     * @param argEncoding バイト長を算出するためのエンコーディング。null指定の場合にはデフォルトエンコーディング。
     * @return 目標となるバイト長に加工された後の文字列。
     */
    public static String padRight(final String argSource, final int argLength, final char argPadChar, final String argEncoding) {
        if (argSource == null) {
            throw new IllegalArgumentException("padRightの入力文字列に nullが与えられました。");
        }

        String result = argSource;
        for (;;) {
            if (getBytesLength(result, argEncoding) >= argLength) {
                break;
            }

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

    /**
     * 与えられた文字列を指定の長さまで左側をパディングします。
     *
     * @param argSource 入力文字列。
     * @param argLength 目標とするトータルバイト長。
     * @param argPadChar 埋める際に利用するパディング文字。
     * @param argEncoding バイト長を算出するためのエンコーディング。null指定の場合にはデフォルトエンコーディング。
     * @return 目標となるバイト長に加工された後の文字列。
     */
    public static String padLeft(final String argSource, final int argLength, final char argPadChar, final String argEncoding) {
        if (argSource == null) {
            throw new IllegalArgumentException("padLeftの入力文字列に nullが与えられました。");
        }

        String result = argSource;
        for (;;) {
            if (getBytesLength(result, argEncoding) >= argLength) {
                break;
            }

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

    /**
     * 与えられた文字列のバイト長を取得します。
     *
     * @param argSource 入力文字列。
     * @param argEncoding バイト長を算出するためのエンコーディング。null指定の場合にはデフォルトエンコーディング。
     * @return 入力文字列のバイト長。
     */
    private static int getBytesLength(final String argSource, final String argEncoding) {
        if (argSource == null) {
            throw new IllegalArgumentException("getBytesLengthの入力文字列に nullが与えられました。");
        }

        if (argEncoding == null) {
            return argSource.getBytes().length;
        } else {
            try {
                return argSource.getBytes(argEncoding).length;
            } catch (UnsupportedEncodingException ex) {
                throw new IllegalArgumentException("サポートされないエンコーディング[" + argEncoding + "]が指定されました。" + ex.toString());
            }
        }
    }
}
