package org.itscool.commons.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class ByteUtil {
    public static final byte[] LINE= {13, 10};
    
    /**
     * 1行分のバイト配列を取得します
     * @param buffer バイト配列
     * @param startPos 取得開始位置
     * @return 1行分のバイト配列を返します
     */
    public static byte[] getLineCrLf(byte[] buffer, int startPos){
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        int bufSize = buffer.length;
        
        //開始行（終了行）キーワード検索
        for(int i=startPos;true;i++) {
            if((i+1)>=bufSize){
                break;
            }else if((buffer[i]==LINE[0])&&(buffer[i+1]==LINE[1])) {
                break;
            }
            bo.write(buffer[i]);
        }
        byte[] byteArray = bo.toByteArray();
        try{
            bo.close();
        }catch(IOException e){}
        
        return byteArray;
    }
    
    /**
     * bufferにkeyが含まれている最初のバイト位置を取得
     * @param buffer バイト配列
     * @param key 検索対象キー
     * @return 最初に見つかったバイト位置
     */
    public static int indexof(byte[] buffer, byte[] key){
        
        int bufSize = buffer.length;
        int keySize = key.length;
        for(int i=0, j=0; i<bufSize; i++ ){
            //不一致
            if(buffer[i]!=key[j]){
                j=0;
                continue;
                //全一致
            }else if( keySize == (j+1) ){
                return (i-keySize);
                //一致
            }else{
                j++;
            }
        }
        return -1;
    }
    
    /**
     * 引数で指定したbyte配列から特定のエリアを抽出し、結果をbyte配列で
     * 返します
     * @param dataB 元データのbyte配列
     * @param off 抽出開始位置
     * @param len 抽出開始位置からのデータ長
     * @return 抽出されたbyte配列を返します
     * @throws IOException
     */
    public static byte[] copyByteData(byte[] dataB, int off, int len){
        try{
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            bo.write(dataB, off, len);
            
            byte[] result = bo.toByteArray();
            bo.close();
            
            return result;
        }catch(IOException ioe){
            return null;
        }
    }
    
    /**
     * 引数に指定されたbyte配列をHEX文字列に変換します
     * @param data byte配列
     * @return HEXに変換された文字列
     */
    public static String convHexString(byte data){
        String hex = Integer.toString(data, 16);
        if(hex.length()==1){
            hex = " 0"+hex;
        }else if(hex.length()==2){
            hex = " "+hex;
        }
        return hex;
    }
    
    public static String debugHex(byte[] data){
        String line = System.getProperty("line.separator");
        StringBuffer sb = new StringBuffer("[BINARY]");
        sb.append("================================================================");
        sb.append(line);
        sb.append(" 00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F");
        sb.append(line);
        sb.append("----------------------------------------------------------------");
        sb.append(line);
        for(int i=0; i<data.length; i++){
            sb.append(convHexString(data[i])+" ");
            if( (i+1)%16 ==0){
                sb.append(line);
            }
        }
        sb.append(line);
        sb.append("================================================================");
        sb.append(line);
        return sb.toString();
    }
    
    public static String debugHex(String data){
        return debugHex(data.getBytes());
    }
}
