package org.maachang.comet.net.ssl ;

import java.io.IOException;
import java.nio.ByteBuffer;

import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;

/**
 * SSLユーティリティ.
 *  
 * @version 2008/06/01
 * @author  masahito suzuki
 * @since   MaachangComet 1.1D
 */
public class SslUtil {
    
    /**
     * 最大バッファサイズ.
     */
    private static final int MAX_BUFFER = 4096 * 48 ;
    
    /**
     * EmptyBuffer.
     */
    public static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0) ;
    
    /**
     * unwrap.
     * @param sslEngine 対象のSSLEngineを設定します.
     * @param buf 対象のバッファを設定します.
     * @param input 対象のInputバッファを設定します.
     * @return SSLEngineResult 戻り値が返されます.
     * @exception Exception 例外.
     */
    public static final SSLEngineResult unwrap( SSLEngine sslEngine,
        ByteBuffer buf,ByteBuffer input ) throws Exception {
        buf.flip() ;
        SSLEngineResult ret = sslEngine.unwrap( buf,input ) ;
        buf.compact() ;
        return ret ;
    }
    
    /**
     * wrap.
     * @param sslEngine 対象のSSLEngineを設定します.
     * @param buf 対象のバッファを設定します.
     * @param output 対象のOutputバッファを設定します.
     * @return SSLEngineResult 戻り値が返されます.
     * @exception Exception 例外.
     */
    public static final SSLEngineResult wrap( SSLEngine sslEngine,
        ByteBuffer buf,ByteBuffer output ) throws Exception {
        if( output.capacity() > MAX_BUFFER ) {
            throw new IOException( "バッファ長は、最大値を越しています" ) ;
        }
        output.clear() ;
        SSLEngineResult ret = sslEngine.wrap( buf,output ) ;
        output.flip() ;
        return ret ;
    }
    
    /**
     * バッファをコピー.
     * @param buf コピー元のバッファを設定します.
     * @return ByteBuffer コピーされたByteBufferが返されます.
     */
    public static final ByteBuffer copy( ByteBuffer buf ) {
        ByteBuffer ret = ByteBuffer.allocate( buf.limit() ) ;
        ret.put( buf ) ;
        ret.flip() ;
        return ret ;
    }
    
    /**
     * バッファサイズを増やす.
     * @param buffer 増やす対象のバッファを設定します.
     * @return ByteBuffer 増えたバッファ情報が返されます.
     * @exception Exception 例外.
     */
    protected static final ByteBuffer reallocate( ByteBuffer buffer )
        throws Exception{
        if( buffer.capacity() > MAX_BUFFER ) {
            throw new IOException( "バッファ長は、最大値を越しています" ) ;
        }
        ByteBuffer t = ByteBuffer.allocate( buffer.capacity() * 2 ) ;
        buffer.flip() ;
        t.put( buffer ) ;
        buffer = t ;
        return buffer ;
    }
    
}

