class Solargraph::LanguageServer::Transport::DataReader

Public Class Methods

new() click to toggle source
# File lib/solargraph/language_server/transport/data_reader.rb, line 9
def initialize
  @in_header = true
  @content_length = 0
  @buffer = String.new
end

Public Instance Methods

receive(data) click to toggle source

Process raw data received from the client. The data will be parsed into messages based on the JSON-RPC protocol. Each message will be passed to the block declared via set_message_handler. Incomplete data will be buffered and subsequent data will be appended to the buffer.

@param data [String]

# File lib/solargraph/language_server/transport/data_reader.rb, line 29
def receive data
  data.each_char do |char|
    @buffer.concat char
    if @in_header
      prepare_to_parse_message if @buffer.end_with?("\r\n\r\n")
    else
      parse_message_from_buffer if @buffer.bytesize == @content_length
    end
  end
end
set_message_handler(&block) click to toggle source

Declare a block to be executed for each message received from the client.

@yieldparam [Hash] The message received from the client

# File lib/solargraph/language_server/transport/data_reader.rb, line 19
def set_message_handler &block
  @message_handler = block
end

Private Instance Methods

parse_message_from_buffer() click to toggle source

@return [void]

# File lib/solargraph/language_server/transport/data_reader.rb, line 56
def parse_message_from_buffer
  begin
    msg = JSON.parse(@buffer)
    @message_handler.call msg unless @message_handler.nil?
  rescue JSON::ParserError => e
    Solargraph::Logging.logger.warn "Failed to parse request: #{e.message}"
    Solargraph::Logging.logger.debug "Buffer: #{@buffer}"
  ensure
    @buffer.clear
    @in_header = true
    @content_length = 0
  end
end
prepare_to_parse_message() click to toggle source

@return [void]

# File lib/solargraph/language_server/transport/data_reader.rb, line 43
def prepare_to_parse_message
  @in_header = false
  @buffer.each_line do |line|
    parts = line.split(':').map(&:strip)
    if parts[0] == 'Content-Length'
      @content_length = parts[1].to_i
      break
    end
  end
  @buffer.clear
end