/*
 * Copyright 2007 nori090
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package jimmy;

import java.net.InetAddress;
import java.net.UnknownHostException;

import org.apache.commons.codec.binary.Hex;

/**
 * convert primitive type
 * 
 * @author nori090
 * @version $Rev: 17 $ $Date: 2008-03-25 22:45:24 +0900 (Tue, 25 Mar 2008) $
 */
public class ConvertUtil {

    private ConvertUtil() {
        super();
    }

    /**
     * Little Endian short bytes
     */
    public static byte[] toLittleEndianBytes( short value ) {
        byte[] ret = new byte[2];
        ret[0] = (byte) ( 0xff & value );
        ret[1] = (byte) ( 0xff & ( value >> 8 ) );
        return ret;
    }
    
    /**
     * Little Endian int bytes
     */
    public static byte[] toLittleEndianBytes( int value ) {
        byte[] ret = new byte[4];
        ret[0] = (byte) ( 0xff & value );
        ret[1] = (byte) ( 0xff & ( value >> 8 ) );
        ret[2] = (byte) ( 0xff & ( value >> 16 ) );
        ret[3] = (byte) ( 0xff & ( value >> 24 ) );
        return ret;
    }

    /**
     * Little Endian long bytes.
     */
    public static byte[] toLittleEndianBytes( long value ) {
        byte[] ret = new byte[8];
        ret[0] = (byte) ( 0xff & value );
        ret[1] = (byte) ( 0xff & ( value >> 8 ) );
        ret[2] = (byte) ( 0xff & ( value >> 16 ) );
        ret[3] = (byte) ( 0xff & ( value >> 24 ) );
        ret[4] = (byte) ( 0xff & ( value >> 32 ) );
        ret[5] = (byte) ( 0xff & ( value >> 40 ) );
        ret[6] = (byte) ( 0xff & ( value >> 48 ) );
        ret[7] = (byte) ( 0xff & ( value >> 56 ) );
        return ret;
    }

    public static int littleEndianBytes2int( byte[] bs ) {
        /*
         * 柔軟に対応してみるテスト
         */
        int i = ( bs.length > 3 ) ? ( ( bs[3] & 0xFF ) << 24 ) : ( ( 0 & 0xFF ) << 24 );
        i = i | ( ( bs.length > 2 ) ? ( ( bs[2] & 0xFF ) << 16 ) : ( ( 0 & 0xFF ) << 16 ) );
        i = i | ( ( bs.length > 1 ) ? ( ( bs[1] & 0xFF ) << 8 ) : ( ( 0 & 0xFF ) << 8 ) );
        i = i | ( ( bs.length > 0 ) ? ( bs[0] & 0xFF ) : ( 0 & 0xFF ) );
        return i;
    }
    
    public static byte[] getCStringByte( byte[] bs ) {
        for ( int i = 0; i < bs.length; i++ ) {
            if ( bs[i] == 0 ) {
                if ( i == 0 ) {
                    return new byte[] { bs[0] };
                }
                else {
                    byte[] new_bs = new byte[i];
                    System.arraycopy( bs, 0, new_bs, 0, i );
                    return new_bs;
                }
            }
        }
        return bs;
    }

    public static void main( String[] args ) {
        System.out.println( Hex.encodeHex( toLittleEndianBytes( 123456789 ) ) );
        System.out.println( littleEndianBytes2int( new byte[] { 0x15, (byte) 0xCD, 0x5B, 0x07 } ) );
        try {
            System.out.println( InetAddress.getByAddress(
                                                          new byte[] { (byte) 0xC0, (byte) 0xA8, (byte) 0x01,
                                                              (byte) 0x0A } ).getHostAddress() );
        }
        catch ( UnknownHostException e ) {
            e.printStackTrace();
        }
        System.out.println( littleEndianBytes2int( new byte[] { (byte) 0xC0, (byte) 0xA8 } ) );
        System.out.println( littleEndianBytes2int( new byte[] { (byte) 0xC0, (byte) 0xA8, 0, 0 } ) );
        System.out.println( Hex.encodeHex( getCStringByte( new byte[] { (byte) 0xBA, 0x70, 0x69, 0x65, 0x77, 0x66,
            0x36, 0x61, 0x73, 0x63, 0x78, 0x6c, 0x76 } ) ) );
        System.out.println( Hex.encodeHex( getCStringByte( new byte[] { (byte) 0xBA, 0x70, 0x00, 0x65, 0x77, 0x66,
            0x36, 0x61, 0x73, 0x63, 0x78, 0x6c, 0x76 } ) ) );
    }
}
