package org.maachang.rimdb.util ;

import org.maachang.rimdb.RimDbException;

/**
 * 変換処理系.
 * 
 * @version 2014/07/07
 * @author  masahito suzuki
 * @since   rimdb-1.00
 */
@SuppressWarnings("deprecation")
public final class ConvertUtil {
    protected ConvertUtil() {} ;
    
    /**
     * 文字列内容が数値かチェック.
     * @param num 対象の文字列を設定します.
     * @return boolean [true]の場合、文字列内は数値が格納されています.
     */
    public static final boolean isNumeric( Object num ) {
        if( num == null ) {
            return false ;
        }
        else if( num instanceof Number ) {
            return true ;
        }
        String s ;
        if( !( num instanceof String ) ) {
            s = num.toString().trim() ;
        }
        else {
            s = ((String)num).trim() ;
        }
        if( s.length() <= 0 ) {
            return false ;
        }
        int start = 0 ;
        if( s.charAt( 0 ) == '-' ) {
            start = 1 ;
        }
        boolean dt = false ;
        int len = s.length() ;
        if( start >= len ) {
            return false ;
        }
        char c ;
        for( int i = start ; i < len ; i ++ ) {
            if( ( c = s.charAt( i ) ) == '.' ) {
                if( dt ) {
                    return false ;
                }
                dt = true ;
            }
            else if( ( c >= '0' && c <= '9' ) == false ) {
                return false ;
            }
        }
        return true ;
    }
    
    /**
     * Boolean変換.
     * @param n 変換対象の条件を設定します.
     * @return 変換された内容が返却されます.
     */
    public static final Boolean convertBool( final Object o ) {
        if( o == null ) {
            return null ;
        }
        else if( o instanceof Boolean ) {
            return (Boolean)o ;
        }
        else if( o instanceof Number ) {
            return ( ( ( Number )o ).intValue() == 0 ) ? false : true ;
        }
        else if( o instanceof String ) {
            String s = ( (String)o ).trim() ;
            if( eqEng( "true",s ) || eqEng( "t",s ) ) {
                return true ;
            }
            else if( eqEng( "false",s ) || eqEng( "f",s ) ) {
                return false ;
            }
        }
        throw new RimDbException( "BOOL型変換に失敗しました[" + o + "]" ) ;
    }
    
    /**
     * Integer変換.
     * @param n 変換対象の条件を設定します.
     * @return 変換された内容が返却されます.
     */
    public static final Integer convertInt( final Object o ) {
        if( o == null ) {
            return null ;
        }
        else if( o instanceof Integer ) {
            return (Integer)o ;
        }
        else if( o instanceof Number ) {
            return ((Number)o).intValue() ;
        }
        else if( o instanceof String && isNumeric( o ) ) {
            return parseInt( ((String)o).trim() ) ;
        }
        throw new RimDbException( "Int型変換に失敗しました[" + o + "]" ) ;
    }
    
    /**
     * Long変換.
     * @param n 変換対象の条件を設定します.
     * @return 変換された内容が返却されます.
     */
    public static final Long convertLong( final Object o ) {
        if( o == null ) {
            return null ;
        }
        else if( o instanceof Long ) {
            return (Long)o ;
        }
        else if( o instanceof Number ) {
            return ((Number)o).longValue() ;
        }
        else if( o instanceof String && isNumeric( o ) ) {
            return parseLong( ((String)o).trim() ) ;
        }
        throw new RimDbException( "Long型変換に失敗しました[" + o + "]" ) ;
    }
    
    /**
     * Float変換.
     * @param n 変換対象の条件を設定します.
     * @return 変換された内容が返却されます.
     */
    public static final Float convertFloat( final Object o ) {
        if( o == null ) {
            return null ;
        }
        else if( o instanceof Float ) {
            return (Float)o ;
        }
        else if( o instanceof Number ) {
            return ((Number)o).floatValue() ;
        }
        else if( o instanceof String && isNumeric( o ) ) {
            return parseFloat( ((String)o).trim() ) ;
        }
        throw new RimDbException( "Float型変換に失敗しました[" + o + "]" ) ;
    }
    
    /**
     * Double変換.
     * @param n 変換対象の条件を設定します.
     * @return 変換された内容が返却されます.
     */
    public static final Double convertDouble( final Object o ) {
        if( o == null ) {
            return null ;
        }
        else if( o instanceof Double ) {
            return (Double)o ;
        }
        else if( o instanceof Number ) {
            return ((Number)o).doubleValue() ;
        }
        else if( o instanceof String && isNumeric( o ) ) {
            return parseDouble( ((String)o).trim() ) ;
        }
        throw new RimDbException( "Double型変換に失敗しました[" + o + "]" ) ;
    }
    
    /**
     * 文字列変換.
     * @param n 変換対象の条件を設定します.
     * @return 変換された内容が返却されます.
     */
    public static final String convertString( final Object o ) {
        if( o == null ) {
            return null ;
        }
        else if( o instanceof String ) {
            return (String)o ;
        }
        return o.toString() ;
    }
    
    
    /** 日付のみ表現. **/
    private static final java.sql.Date _cDate( final long d ) {
        return _cDate( new java.util.Date( d ) ) ;
    }
    private static final java.sql.Date _cDate( final java.util.Date n ) {
        return new java.sql.Date( n.getYear(),n.getMonth(),n.getDate() ) ;
    }
    
    /**
     * 日付変換.
     * @param n 変換対象の条件を設定します.
     * @return 変換された内容が返却されます.
     */
    public static final java.sql.Date convertSqlDate( final Object o ) {
        if( o == null ) {
            return null ;
        }
        else if( o instanceof java.util.Date ) {
            return _cDate( ( ( java.util.Date )o ) ) ;
        }
        else if( o instanceof Long ) {
            return _cDate( (Long)o ) ;
        }
        else if( o instanceof Number ) {
            return _cDate( ((Number)o).longValue() ) ;
        }
        else if( o instanceof String ) {
            if( isNumeric( o ) ) {
                return _cDate( parseLong((String)o) ) ;
            }
            return DateTimeUtil.getDate( (String)o ) ;
        }
        throw new RimDbException( "java.sql.Date型変換に失敗しました[" + o + "]" ) ;
    }
    
    /** 時間のみ表現. **/
    private static final java.sql.Time _cTime( final long d ) {
        return _cTime( new java.util.Date( d ) ) ;
    }
    private static final java.sql.Time _cTime( final java.util.Date n ) {
        return new java.sql.Time( n.getHours(),n.getMinutes(),n.getSeconds() ) ;
    }
    
    /**
     * 時間変換.
     * @param n 変換対象の条件を設定します.
     * @return 変換された内容が返却されます.
     */
    public static final java.sql.Time convertSqlTime( final Object o ) {
        if( o == null ) {
            return null ;
        }
        else if( o instanceof java.util.Date ) {
            return _cTime( ( java.util.Date )o ) ;
        }
        else if( o instanceof Long ) {
            return _cTime( (Long)o ) ;
        }
        else if( o instanceof Number ) {
            return _cTime( ((Number)o).longValue() ) ;
        }
        else if( o instanceof String ) {
            if( isNumeric( (String)o ) ) {
                return _cTime( parseLong((String)o) ) ;
            }
            return DateTimeUtil.getTime( (String)o ) ;
        }
        throw new RimDbException( "java.sql.Time型変換に失敗しました[" + o + "]" ) ;
    }
    
    /**
     * 日付時間変換.
     * @param n 変換対象の条件を設定します.
     * @return 変換された内容が返却されます.
     */
    public static final java.sql.Timestamp convertSqlTimestamp( final Object o ) {
        if( o == null ) {
            return null ;
        }
        else if( o instanceof java.util.Date ) {
            if( o instanceof java.sql.Timestamp ) {
                return ( java.sql.Timestamp )o ;
            }
            return new java.sql.Timestamp( ( ( java.util.Date )o ).getTime() ) ;
        }
        else if( o instanceof Long ) {
            return new java.sql.Timestamp( (Long)o ) ;
        }
        else if( o instanceof Number ) {
            return new java.sql.Timestamp( ((Number)o).longValue() ) ;
        }
        else if( o instanceof String ) {
            if( isNumeric( (String)o ) ) {
                return new java.sql.Timestamp( parseLong((String)o) ) ;
            }
            return DateTimeUtil.getTimestamp( (String)o ) ;
        }
        throw new RimDbException( "java.sql.Timestamp型変換に失敗しました[" + o + "]" ) ;
    }
    
    /**
     * 通常日付変換.
     * @param n 変換対象の条件を設定します.
     * @return 変換された内容が返却されます.
     */
    public static final java.util.Date convertDate( final Object o ) {
        if( o == null ) {
            return null ;
        }
        if( o instanceof java.util.Date ) {
            return ( java.util.Date )o ;
        }
        else if( o instanceof Long ) {
            return new java.util.Date( (Long)o ) ;
        }
        else if( o instanceof Number ) {
            return new java.util.Date( ((Number)o).longValue() ) ;
        }
        else if( o instanceof String ) {
            if( isNumeric( (String)o ) ) {
                return new java.sql.Timestamp( parseLong((String)o) ) ;
            }
            return DateTimeUtil.getTimestamp( (String)o ) ;
        }
        throw new RimDbException( "java.util.Date型変換に失敗しました[" + o + "]" ) ;
    }
    
    /**
     * 文字列から、Boolean型に変換.
     * @param s 対象の文字列を設定します.
     * @return boolean Boolean型が返されます.
     */
    public static final boolean parseBoolean( final String s ) {
        if( s == null || s.length() <= 0 ) {
            throw new IllegalArgumentException( "文字列は空です" ) ;
        }
        if( eqEng( "true",s ) ) {
            return true ;
        }
        else if( eqEng( "false",s ) ) {
            return false ;
        }
        throw new RimDbException( "Boolean変換に失敗しました:"+s ) ;
    }
    
    /**
     * 文字列から、int型数値に変換.
     * @param num 対象の文字列を設定します.
     * @return int int型で変換された数値が返されます.
     */
    public static final int parseInt( final String num ) {
        int len ;
        if( num == null || ( len = num.length() ) <= 0 ) {
            throw new IllegalArgumentException( "文字列は空です" ) ;
        }
        int ret = 0 ;
        int end = 0 ;
        int v ;
        if( num.charAt( 0 ) == '-' ) {
            end = 1 ;
        }
        if( ( v = num.indexOf( "." ) ) != -1 ) {
            len = v ;
        }
        char c ;
        v = 1 ;
        for( int i = len-1 ; i >= end ; i -- ) {
            c = num.charAt( i ) ;
            if( c >= '0' && c <= '9' ) {
                ret += ( v * (int)( c - '0' ) ) ;
                v *= 10 ;
            }
            else {
                throw new RimDbException( "数値変換に失敗しました:"+num ) ;
            }
        }
        if( end == 1 ) {
            return ret * -1 ;
        }
        return ret ;
    }
    
    /**
     * 文字列から、long型数値に変換.
     * @param num 対象の文字列を設定します.
     * @return long long型で変換された数値が返されます.
     */
    public static final long parseLong( final String num ) {
        int len ;
        if( num == null || ( len = num.length() ) <= 0 ) {
            throw new IllegalArgumentException( "文字列は空です" ) ;
        }
        long ret = 0L ;
        int end = 0 ;
        int dot ;
        if( num.charAt( 0 ) == '-' ) {
            end = 1 ;
        }
        if( ( dot = num.indexOf( "." ) ) != -1 ) {
            len = dot ;
        }
        char c ;
        long v = 1L ;
        for( int i = len-1 ; i >= end ; i -- ) {
            c = num.charAt( i ) ;
            if( c >= '0' && c <= '9' ) {
                ret += ( v * (long)( c - '0' ) ) ;
                v *= 10L ;
            }
            else {
                throw new RimDbException( "数値変換に失敗しました:"+num ) ;
            }
        }
        if( end == 1 ) {
            return ret * -1L ;
        }
        return ret ;
    }
    
    /**
     * 文字列から、float型数値に変換.
     * @param num 対象の文字列を設定します.
     * @return float float型で変換された数値が返されます.
     */
    public static final float parseFloat( final String num ) {
        int len ;
        if( num == null || ( len = num.length() ) <= 0 ) {
            throw new IllegalArgumentException( "文字列は空です" ) ;
        }
        float ret = 0f ;
        int end = 0 ;
        int dot ;
        if( num.charAt( 0 ) == '-' ) {
            end = 1 ;
        }
        char c ;
        float v = 1f ;
        if( ( dot = num.indexOf( "." ) ) == -1 ) {
            for( int i = len-1 ; i >= end ; i -- ) {
                c = num.charAt( i ) ;
                if( c >= '0' && c <= '9' ) {
                    ret += ( v * (float)( c - '0' ) ) ;
                    v *= 10f ;
                }
                else {
                    throw new RimDbException( "数値変換に失敗しました:"+num ) ;
                }
            }
            if( end == 1 ) {
                return ret * -1f ;
            }
            return ret ;
        }
        else {
            for( int i = dot-1 ; i >= end ; i -- ) {
                c = num.charAt( i ) ;
                if( c >= '0' && c <= '9' ) {
                    ret += ( v * (float)( c - '0' ) ) ;
                    v *= 10f ;
                }
                else {
                    throw new RimDbException( "数値変換に失敗しました:"+num ) ;
                }
            }
            float dret = 0f ;
            v = 1f ;
            for( int i = len-1 ; i > dot ; i -- ) {
                c = num.charAt( i ) ;
                if( c >= '0' && c <= '9' ) {
                    dret += ( v * (float)( c - '0' ) ) ;
                    v *= 10f ;
                }
                else {
                    throw new RimDbException( "数値変換に失敗しました:"+num ) ;
                }
            }
            if( end == 1 ) {
                ret = ( ret + ( dret / v ) ) * -1f ;
            }
            else {
                ret += ( dret / v ) ;
            }
            return ret ;
        }
    }
    
    /**
     * 文字列から、double型数値に変換.
     * @param num 対象の文字列を設定します.
     * @return double double型で変換された数値が返されます.
     */
    public static final double parseDouble( final String num ) {
        int len ;
        if( num == null || ( len = num.length() ) <= 0 ) {
            throw new IllegalArgumentException( "文字列は空です" ) ;
        }
        double ret = 0d ;
        int end = 0 ;
        int dot ;
        if( num.charAt( 0 ) == '-' ) {
            end = 1 ;
        }
        char c ;
        double v = 1d ;
        if( ( dot = num.indexOf( "." ) ) == -1 ) {
            for( int i = len-1 ; i >= end ; i -- ) {
                c = num.charAt( i ) ;
                if( c >= '0' && c <= '9' ) {
                    ret += ( v * (double)( c - '0' ) ) ;
                    v *= 10d ;
                }
                else {
                    throw new RimDbException( "数値変換に失敗しました:"+num ) ;
                }
            }
            if( end == 1 ) {
                return ret * -1d ;
            }
            return ret ;
        }
        else {
            for( int i = dot-1 ; i >= end ; i -- ) {
                c = num.charAt( i ) ;
                if( c >= '0' && c <= '9' ) {
                    ret += ( v * (double)( c - '0' ) ) ;
                    v *= 10d ;
                }
                else {
                    throw new RimDbException( "数値変換に失敗しました:"+num ) ;
                }
            }
            double dret = 0d ;
            v = 1d ;
            for( int i = len-1 ; i > dot ; i -- ) {
                c = num.charAt( i ) ;
                if( c >= '0' && c <= '9' ) {
                    dret += ( v * (double)( c - '0' ) ) ;
                    v *= 10d ;
                }
                else {
                    throw new RimDbException( "数値変換に失敗しました:"+num ) ;
                }
            }
            if( end == 1 ) {
                ret = ( ret + ( dret / v ) ) * -1d ;
            }
            else {
                ret += ( dret / v ) ;
            }
            return ret ;
        }
    }
    
    /**
     * boolean群を定義.
     * @param v boolean群を設定します.
     * @return boolean[] boolean群が返却されます.
     */
    public static final boolean[] getArray( boolean... v ) {
        return v ;
    }
    
    /**
     * int群を定義.
     * @param v int群を設定します.
     * @return int[] int群が返却されます.
     */
    public static final int[] getArray( int... v ) {
        return v ;
    }
    
    /**
     * long群を定義.
     * @param v long群を設定します.
     * @return long[] long群が返却されます.
     */
    public static final long[] getArray( long... v ) {
        return v ;
    }
    
    /**
     * float群を定義.
     * @param v float群を設定します.
     * @return float[] float群が返却されます.
     */
    public static final float[] getArray( float... v ) {
        return v ;
    }
    
    /**
     * double群を定義.
     * @param v double群を設定します.
     * @return double[] double群が返却されます.
     */
    public static final double[] getArray( double... v ) {
        return v ;
    }
    
    /**
     * java.sql.Date群を定義.
     * @param v java.sql.Date群を設定します.
     * @return java.sql.java.sql.Date[] double群が返却されます.
     */
    public static final java.sql.Date[] getArray( java.sql.Date... v ) {
        return v ;
    }
    
    /**
     * java.sql.Time群を定義.
     * @param v java.sql.Time群を設定します.
     * @return java.sql.java.sql.Time[] double群が返却されます.
     */
    public static final java.sql.Time[] getArray( java.sql.Time... v ) {
        return v ;
    }
    
    /**
     * java.sql.Timestamp群を定義.
     * @param v java.sql.Timestamp群を設定します.
     * @return java.sql.java.sql.Timestamp[] double群が返却されます.
     */
    public static final java.sql.Timestamp[] getArray( java.sql.Timestamp... v ) {
        return v ;
    }
    
    /**
     * String群を定義.
     * @param v String群を設定します.
     * @return String[] String群が返却されます.
     */
    public static final String[] getArray( String... v ) {
        return v ;
    }
    
    /**
     * Comparable群を定義.
     * @param v Comparable群を設定します.
     * @return Comparable[] Comparable群が返却されます.
     */
    @SuppressWarnings("unchecked")
    public static final Comparable[] getArray( Comparable... v ) {
        return v ;
    }
    
    /**
     * Object群を定義.
     * @param v Object群を設定します.
     * @return Object[] Object群が返却されます.
     */
    public static final Object[] getArray( Object... v ) {
        return v ;
    }
    
    /**
     * ビットマスク長を取得.
     * @param x 対象の値を設定します.
     * @return int ビットマスク長が返却されます.
     */
    public static final int bitMask( int x ) {
        if( x < 1 ) {
            return 1 ;
        }
        x |= ( x >>  1 );
        x |= ( x >>  2 );
        x |= ( x >>  4 );
        x |= ( x >>  8 );
        x |= ( x >> 16 );
        x = (x & 0x55555555) + (x >> 1 & 0x55555555);
        x = (x & 0x33333333) + (x >> 2 & 0x33333333);
        x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f);
        x = (x & 0x00ff00ff) + (x >> 8 & 0x00ff00ff);
        x = (x & 0x0000ffff) + (x >>16 & 0x0000ffff);
        return 1 << ( ( (x & 0x0000ffff) + (x >>16 & 0x0000ffff) ) - 1 ) ;
    }
    
    /** 小文字、大文字の幅.**/
    private static final int SMALL_BIG_CODE = (int)'a' - (int)'A' ;
    
    /**
     * 英字の大文字小文字を区別せずにチェック.
     * @param src 比較元文字を設定します.
     * @param dest 比較先文字を設定します.
     * @return boolean [true]の場合、一致します.
     */
    public static final boolean eqEng( final String src,final String dest ) {
        if( src == null || dest == null ) {
            return false ;
        }
        int len = src.length() ;
        if( len != dest.length() ) {
            return false ;
        }
        char s,d ;
        for( int i = 0 ; i < len ; i ++ ) {
            if( (s = src.charAt( i ) ) == (d = dest.charAt( i ) ) ||
                ( s >= 'A' && s <= 'z' &&
                d >= 'A' && d <= 'z' &&
                ( s + SMALL_BIG_CODE == d ||
                s - SMALL_BIG_CODE == d ||
                s == d + SMALL_BIG_CODE ||
                s == d - SMALL_BIG_CODE ||
                s + SMALL_BIG_CODE == d + SMALL_BIG_CODE ||
                s - SMALL_BIG_CODE == d + SMALL_BIG_CODE ||
                s + SMALL_BIG_CODE == d - SMALL_BIG_CODE ||
                s - SMALL_BIG_CODE == d - SMALL_BIG_CODE ) ) ) {
                continue ;
            }
            return false ;
        }
        return true ;
    }
    
    /**
     * 英字の大文字小文字を区別せずにチェック.
     * @param src 比較元文字を設定します.
     * @param start srcのチェック開始位置を設定します.
     * @param end srcのチェック終了位置を設定します.
     * @param dest 比較先文字を設定します.
     * @return boolean [true]の場合、一致します.
     */
    public static final boolean eqEng( String src,int start,int end,String dest ) {
        if( src == null || dest == null ) {
            return false ;
        }
        final int len = end - start ;
        if( len != dest.length() ) {
            return false ;
        }
        char s,d ;
        for( int i = 0 ; i < len ; i ++ ) {
            if( (s = src.charAt( i+start ) ) == (d = dest.charAt( i ) ) ||
                ( s >= 'A' && s <= 'z' &&
                d >= 'A' && d <= 'z' &&
                ( s + SMALL_BIG_CODE == d ||
                s - SMALL_BIG_CODE == d ||
                s == d + SMALL_BIG_CODE ||
                s == d - SMALL_BIG_CODE ||
                s + SMALL_BIG_CODE == d + SMALL_BIG_CODE ||
                s - SMALL_BIG_CODE == d + SMALL_BIG_CODE ||
                s + SMALL_BIG_CODE == d - SMALL_BIG_CODE ||
                s - SMALL_BIG_CODE == d - SMALL_BIG_CODE ) ) ) {
                continue ;
            }
            return false ;
        }
        return true ;
    }
    
    /**
     * 文字情報の置き換え.
     * @param src 置き換え元の文字列を設定します.
     * @param s 置き換え文字条件を設定します.
     * @param d 置き換え先の文字条件を設定します.
     * @return String 文字列が返却されます.
     */
    public static final String changeString( String src,String s,String d ) {
        return changeString( src,0,src.length(),s,d ) ;
    }
    
    /**
     * 文字情報の置き換え.
     * @param src 置き換え元の文字列を設定します.
     * @param off 置き換え元文字のオフセット値を設定します.
     * @param len 置き換え元文字の長さを設定します.
     * @param s 置き換え文字条件を設定します.
     * @param d 置き換え先の文字条件を設定します.
     * @return String 文字列が返却されます.
     */
    public static final String changeString( String src,int off,int len,String s,String d ) {
        int j,k ;
        char t = s.charAt( 0 ) ;
        int lenS = s.length() ;
        StringBuilder buf = new StringBuilder( len ) ;
        for( int i = off ; i < len ; i ++ ) {
            if( src.charAt( i ) == t ) {
                j = i ; k = 0 ;
                while( ++ k < lenS && ++ j < len && src.charAt( j ) == s.charAt( k ) ) ;
                if( k >= lenS ) {
                    buf.append( d ) ;
                    i += (lenS-1) ;
                }
                else {
                    buf.append( t ) ;
                }
            }
            else {
                buf.append( src.charAt( i ) ) ;
            }
        }
        return buf.toString() ;
    }
    
    /**
     * 指定文字内のコーテーションインデントを1つ上げる.
     * @param string 対象の文字列を設定します.
     * @param indent 対象のインデント値を設定します.
     *               0を設定した場合は１つインデントを増やします。
     *               -1を設定した場合は１つインデントを減らします。
     * @param dc [true]の場合、ダブルコーテーションで処理します.
     * @return String 変換された文字列が返されます.
     */
    public static final String indentCote( String string,int indent,boolean dc ) {
        if( string == null || string.length() <= 0 ) {
            return string ;
        }
        char cote = ( dc ) ? '\"' : '\'' ;
        int len = string.length() ;
        char c ;
        int j ;
        int yenLen = 0 ;
        StringBuilder buf = new StringBuilder( (int)( len * 1.25d ) ) ;
        for( int i = 0 ; i < len ; i ++ ) {
            if( ( c = string.charAt( i ) ) == cote ) {
                if( yenLen > 0 ) {
                    if( indent == -1 ) {
                        yenLen >>= 1 ;
                    }
                    else {
                        yenLen <<= 1 ;
                    }
                    for( j = 0 ; j < yenLen ; j ++ ) {
                        buf.append( "\\" ) ;
                    }
                    yenLen = 0 ;
                }
                if( indent == -1 ) {
                    buf.append( cote ) ;
                }
                else {
                    buf.append( "\\" ).append( cote ) ;
                }
            }
            else if( '\\' == c ) {
                yenLen ++ ;
            }
            else {
                if( yenLen != 0 ) {
                    for( j = 0 ; j < yenLen ; j ++ ) {
                        buf.append( "\\" ) ;
                    }
                    yenLen = 0 ;
                }
                buf.append( c ) ;
            }
        }
        if( yenLen != 0 ) {
            for( j = 0 ; j < yenLen ; j ++ ) {
                buf.append( "\\" ) ;
            }
        }
        return buf.toString() ;
    }
    
    /**
     * 指定文字内のダブルコーテーションインデントを1つ上げる.
     * @param string 対象の文字列を設定します.
     * @return String 変換された文字列が返されます.
     */
    public static final String upIndentDoubleCote( String string ) {
        return indentCote( string,0,true ) ;
    }
    
    /**
     * 指定文字内のシングルコーテーションインデントを1つ上げる.
     * @param string 対象の文字列を設定します.
     * @return String 変換された文字列が返されます.
     */
    public static final String upIndentSingleCote( String string ) {
        return indentCote( string,0,false ) ;
    }
    
    /**
     * 指定文字内のダブルコーテーションインデントを1つ下げる.
     * @param string 対象の文字列を設定します.
     * @return String 変換された文字列が返されます.
     */
    public static final String downIndentDoubleCote( String string ) {
        // 文字列で検出されるダブルコーテーションが￥始まりの場合は、処理する.
        boolean exec = false ;
        int len = string.length() ;
        char c,b ;
        b = 0 ;
        for( int i = 0 ; i < len ; i ++ ) {
            c = string.charAt( i ) ;
            if( c == '\"' ) {
                if( b == '\\' ) {
                    exec = true ;
                }
                break ;
            }
            b = c ;
        }
        if( exec ) {
            return indentCote( string,-1,true ) ;
        }
        return string ;
    }
    
    /**
     * 指定文字内のシングルコーテーションインデントを1つ下げる.
     * @param string 対象の文字列を設定します.
     * @return String 変換された文字列が返されます.
     */
    public static final String downIndentSingleCote( String string ) {
        // 文字列で検出されるシングルコーテーションが￥始まりの場合は、処理する.
        boolean exec = false ;
        int len = string.length() ;
        char c,b ;
        b = 0 ;
        for( int i = 0 ; i < len ; i ++ ) {
            c = string.charAt( i ) ;
            if( c == '\'' ) {
                if( b == '\\' ) {
                    exec = true ;
                }
                break ;
            }
            b = c ;
        }
        if( exec ) {
            return indentCote( string,-1,false ) ;
        }
        return string ;
    }
    
}
