Package org.java_websocket.framing

Source Code of org.java_websocket.framing.CloseFrameBuilder

package org.java_websocket.framing;

import java.nio.ByteBuffer;

import org.java_websocket.exceptions.InvalidDataException;
import org.java_websocket.exceptions.InvalidFrameException;
import org.java_websocket.util.Charsetfunctions;

public class CloseFrameBuilder extends FramedataImpl1 implements CloseFrame {

  static final ByteBuffer emptybytebuffer = ByteBuffer.allocate( 0 );

  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 {
    if( m == null ) {
      m = "";
    }
    // CloseFrame.TLS_ERROR is not allowed to be transfered over the wire
    if( code == CloseFrame.TLS_ERROR ) {
      code = CloseFrame.NOCODE;
      m = "";
    }
    if( code == CloseFrame.NOCODE ) {
      if( 0 < m.length() ) {
        throw new InvalidDataException( PROTOCOL_ERROR, "A close frame must have a closecode if it has a reason" );
      }
      return;// empty payload
    }

    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 );
    pay.rewind();
    setPayload( pay );
  }

  private void initCloseCode() throws InvalidFrameException {
    code = CloseFrame.NOCODE;
    ByteBuffer payload = super.getPayloadData();
    payload.mark();
    if( payload.remaining() >= 2 ) {
      ByteBuffer bb = ByteBuffer.allocate( 4 );
      bb.position( 2 );
      bb.putShort( payload.getShort() );
      bb.position( 0 );
      code = bb.getInt();

      if( code == CloseFrame.ABNORMAL_CLOSE || code == CloseFrame.TLS_ERROR || code == CloseFrame.NOCODE || code > 4999 || code < 1000 || code == 1004 ) {
        throw new InvalidFrameException( "closecode must not be sent over the wire: " + code );
      }
    }
    payload.reset();
  }

  @Override
  public int getCloseCode() {
    return code;
  }

  private void initMessage() throws InvalidDataException {
    if( code == CloseFrame.NOCODE ) {
      reason = Charsetfunctions.stringUtf8( super.getPayloadData() );
    } else {
      ByteBuffer b = super.getPayloadData();
      int mark = b.position();// because stringUtf8 also creates a mark
      try {
        b.position( b.position() + 2 );
        reason = Charsetfunctions.stringUtf8( b );
      } catch ( IllegalArgumentException e ) {
        throw new InvalidFrameException( e );
      } finally {
        b.position( mark );
      }
    }
  }

  @Override
  public String getMessage() {
    return reason;
  }

  @Override
  public String toString() {
    return super.toString() + "code: " + code;
  }

  @Override
  public void setPayload( ByteBuffer payload ) throws InvalidDataException {
    super.setPayload( payload );
    initCloseCode();
    initMessage();
  }
  @Override
  public ByteBuffer getPayloadData() {
    if( code == NOCODE )
      return emptybytebuffer;
    return super.getPayloadData();
  }

}
TOP

Related Classes of org.java_websocket.framing.CloseFrameBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.