package org.maachang.util;


/**
 * バイナリバッファ.
 * 
 * @version 2008/03/25
 * @author masahito suzuki
 * @since MaachangBase 1.00
 */
public class BinaryBuffer {
    private static final int BUFFER = 1024 ;
    private byte[] binary = null ;
    private int pos = 0 ;
    
    public BinaryBuffer() {
        this( -1 ) ;
    }
    
    public BinaryBuffer( int size ) {
        if( size <= 0 ) {
            size = BUFFER ;
        }
        this.binary = new byte[ size ] ;
        this.pos = 0 ;
    }
    
    protected void finalize() throws Exception {
        this.destroy() ;
    }
    
    public void destroy() {
        this.binary = null ;
        this.pos = 0 ;
    }
    
    public int position( int pos ) {
        if( pos <= -1 ) {
            return this.pos ;
        }
        if( this.binary.length < pos ) {
            addLimit( pos - this.binary.length ) ;
            this.pos = pos ;
        }
        else {
            this.pos = pos ;
        }
        return this.pos ;
    }
    
    public int position() {
        return pos ;
    }
    
    public void write( int b ) throws Exception {
        addLimit( 1 ) ;
        binary[ pos ] = ( byte )( b & 0x000000ff ) ;
        pos ++ ;
    }
    
    public void write( byte[] bin ) throws Exception {
        if( bin == null || bin.length <= 0 ) {
            return ;
        }
        write( bin,-1 ) ;
    }
    
    public void write( byte[] bin,int len ) throws Exception {
        if( bin == null || bin.length <= 0 ) {
            return ;
        }
        if( len <= 0 || bin.length <= len ) {
            len = bin.length ;
        }
        addLimit( len ) ;
        int off = this.pos ;
        System.arraycopy( bin,0,this.binary,off,len ) ;
        this.pos += len ;
    }
    
    public byte getByte( int no ) {
        return binary[ no ] ;
    }
    
    public byte[] getRawBinary() {
        return binary ;
    }
    
    public byte[] getBinary() {
        return getBinary( 0 ) ;
    }
    
    public byte[] getBinary( int length ) {
        if( length > binary.length ) {
            return this.binary ;
        }
        byte[] ret = new byte[ length ] ;
        System.arraycopy( this.binary,0,ret,0,length ) ;
        return ret ;
    }
    
    private void addLimit( int len ) {
        if( binary.length <= pos + len ) {
            byte[] t = binary ;
            int iLen = ( t.length * 2 ) + len ;
            binary = new byte[ iLen ] ;
            System.arraycopy( t,0,binary,0,t.length ) ;
            t = null ;
        }
    }
}
