package net.tootallnate.websocket; import java.nio.ByteBuffer; import net.tootallnate.websocket.exeptions.InvalidDataException; import net.tootallnate.websocket.exeptions.InvalidFrameException; public class CloseFrameBuilder extends FramedataImpl1 implements CloseFrame { private int code; private String reason; public CloseFrameBuilder() { super( Opcode.CLOSING ); setFin( true ); } public CloseFrameBuilder( int code ) throws InvalidDataException { super( Opcode.CLOSING ); setFin( true ); setCodeAndMessage( code, "" ); } public CloseFrameBuilder( int code , String m ) throws InvalidDataException { super( Opcode.CLOSING ); setFin( true ); setCodeAndMessage( code, m ); } private void setCodeAndMessage( int code, String m ) throws InvalidDataException { byte[] by = Charsetfunctions.utf8Bytes( m ); ByteBuffer buf = ByteBuffer.allocate( 4 ); buf.putInt( code ); buf.position( 2 ); ByteBuffer pay = ByteBuffer.allocate( 2 + by.length ); pay.put( buf ); pay.put( by ); setPayload( pay.array() ); } private void initCloseCode() throws InvalidFrameException { code = CloseFrame.NOCODE; byte[] payload = getPayloadData(); if( payload.length >= 2 ) { ByteBuffer bb = ByteBuffer.allocate( 4 ); bb.position( 2 ); bb.put( payload, 0, 2 ); bb.position( 0 ); code = bb.getInt(); if( code < 0 || code > Short.MAX_VALUE ) code = CloseFrame.NOCODE; if( code < CloseFrame.NORMAL || code > CloseFrame.EXTENSION || code == NOCODE || code == 1004 ) { throw new InvalidFrameException( "bad code " + code ); } } } @Override public int getCloseCode() { return code; } private void initMessage() throws InvalidDataException { if( code == CloseFrame.NOCODE ) { reason = Charsetfunctions.stringUtf8( getPayloadData() ); } else { byte[] payload = getPayloadData(); reason = Charsetfunctions.stringUtf8( payload, 2, payload.length - 2 ); } } @Override public String getMessage() { return reason; } @Override public String toString() { return super.toString() + "code: " + code; } @Override public void setPayload( byte[] payload ) throws InvalidDataException { super.setPayload( payload ); initCloseCode(); initMessage(); } @Override public byte[] getPayloadData() { if( code == NOCODE ) return new byte[ 0 ]; return super.getPayloadData(); } }