class WebSocket::Driver::Hybi

def emit_frame

def emit_frame
  payload = @masked ? Mask.mask(@payload, @mask) : @payload
  case @opcode
    when OPCODES[:continuation] then
      return fail(:protocol_error, 'Received unexpected continuation frame') unless @mode
      @buffer.concat(payload)
      if @final
        message = @buffer
        message = Driver.encode(message, :utf8) if @mode == :text
        reset
        if message
          emit(:message, MessageEvent.new(message))
        else
          fail(:encoding_error, 'Could not decode a text frame as UTF-8')
        end
      end
    when OPCODES[:text] then
      if @final
        message = Driver.encode(payload, :utf8)
        if message
          emit(:message, MessageEvent.new(message))
        else
          fail(:encoding_error, 'Could not decode a text frame as UTF-8')
        end
      else
        @mode = :text
        @buffer.concat(payload)
      end
    when OPCODES[:binary] then
      if @final
        emit(:message, MessageEvent.new(payload))
      else
        @mode = :binary
        @buffer.concat(payload)
      end
    when OPCODES[:close] then
      code = (payload.size >= 2) ? 256 * payload[0] + payload[1] : nil
      unless (payload.size == 0) or
             (code && code >= MIN_RESERVED_ERROR && code <= MAX_RESERVED_ERROR) or
             ERROR_CODES.include?(code)
        code = ERRORS[:protocol_error]
      end
      message = Driver.encode(payload[2..-1] || [], :utf8)
      if payload.size > 125 or message.nil?
        code = ERRORS[:protocol_error]
      end
      reason = (payload.size > 2) ? message : ''
      shutdown(code, reason || '')
    when OPCODES[:ping] then
      frame(payload, :pong)
    when OPCODES[:pong] then
      message = Driver.encode(payload, :utf8)
      callback = @ping_callbacks[message]
      @ping_callbacks.delete(message)
      callback.call if callback
  end
end