Class: Dms::Tier1::InlineValueParser

Inherits:
Object
  • Object
show all
Defined in:
lib/dms/tier1.rb

Overview

── InlineValueParser ────────────────────────────────────────────────────

A thin wrapper that delegates value parsing to a real Dms::Parser instance, positioned at a specific offset in the source. We extract the source substring from the current position to end-of-line (plus the rest of the document for block values), parse one value, and map back the consumed bytes.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(src, start_pos, start_line, start_line_start, outer) ⇒ InlineValueParser

Returns a new instance of InlineValueParser.



1600
1601
1602
1603
1604
1605
1606
1607
# File 'lib/dms/tier1.rb', line 1600

def initialize(src, start_pos, start_line, start_line_start, outer)
  @src = src
  @pos = start_pos
  @line = start_line
  @line_start = start_line_start
  @outer = outer
  @len = src.bytesize
end

Instance Attribute Details

#lineObject (readonly)

Returns the value of attribute line.



1598
1599
1600
# File 'lib/dms/tier1.rb', line 1598

def line
  @line
end

#line_startObject (readonly)

Returns the value of attribute line_start.



1598
1599
1600
# File 'lib/dms/tier1.rb', line 1598

def line_start
  @line_start
end

#posObject (readonly)

Returns the value of attribute pos.



1598
1599
1600
# File 'lib/dms/tier1.rb', line 1598

def pos
  @pos
end

Instance Method Details

#parse_one_valueObject



1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
# File 'lib/dms/tier1.rb', line 1609

def parse_one_value
  # Build a sub-source from @pos onwards, but we need an offset trick.
  # We'll use Dms::Parser directly, padding the prefix with spaces so
  # line numbers are approximately correct. Since error messages in
  # parameter parsing use the outer parser's position, this is fine.
  sub_src = @src.byteslice(@pos, @len - @pos).force_encoding("UTF-8")

  # Use a real Parser in lite mode to parse one value.
  # We only need one token; the parser will stop at the right place.
  p = SingleValueParser.new(sub_src)
  val = p.parse_value_at_start
  consumed = p.consumed
  # Update position
  new_src_pos = @pos + consumed
  # Update line counts based on consumed newlines
  consumed_src = @src.byteslice(@pos, consumed)
  consumed_src.each_byte do |b|
    if b == 0x0A
      @line += 1
      @line_start = @pos + (@src.byteslice(@pos, consumed).index("\n".force_encoding("UTF-8"), 0) || 0) + 1
    end
  end
  # Recount properly
  @line = 1 + @src.byteslice(0, new_src_pos).count("\n")
  last_nl = @src.byteslice(0, new_src_pos).rindex("\n")
  @line_start = last_nl ? last_nl + 1 : 0
  @pos = new_src_pos
  val
end