Class: Quonfig::SSEConfigClient::LineReader

Inherits:
Object
  • Object
show all
Defined in:
lib/quonfig/sse_config_client.rb

Overview

Byte-level line reader. Accepts arbitrary chunks, yields one UTF-8 line per call to the block. Terminator-stripped (CR / LF / CRLF supported). Modeled on ld-eventsource’s BufferedLineReader — same invariants: split bytes-not-chars while scanning, force-encode to UTF-8 only once a complete line is sliced out, so a multi-byte character spanning two chunks does not raise Encoding::CompatibilityError.

Instance Method Summary collapse

Constructor Details

#initializeLineReader

Returns a new instance of LineReader.



576
577
578
579
# File 'lib/quonfig/sse_config_client.rb', line 576

def initialize
  @buffer = +''.b
  @last_was_cr = false
end

Instance Method Details

#feed(chunk) ⇒ Object



581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
# File 'lib/quonfig/sse_config_client.rb', line 581

def feed(chunk)
  @buffer << chunk.b
  loop do
    idx = @buffer.index(/[\r\n]/)
    break if idx.nil?

    ch = @buffer[idx]
    if idx.zero? && ch == "\n" && @last_was_cr
      # Dangling LF of a CRLF pair split across chunks — consume and skip.
      @last_was_cr = false
      @buffer.slice!(0, 1)
      next
    end

    line = @buffer[0, idx].force_encoding('UTF-8')
    consume = idx + 1
    @last_was_cr = false
    if ch == "\r"
      if consume == @buffer.bytesize
        # CR at end of buffer — could be CRLF split across feeds.
        @last_was_cr = true
      elsif @buffer[consume] == "\n"
        consume += 1
      end
    end
    @buffer.slice!(0, consume)
    yield line
  end
end