Class: Psych::Pure::Source
- Inherits:
-
Object
- Object
- Psych::Pure::Source
- Defined in:
- lib/psych/pure.rb
Overview
A source wraps the input string and provides methods to access line and column information from a byte offset.
Instance Attribute Summary collapse
-
#trim_line ⇒ Object
readonly
The line index computed by the most recent call to #trim.
Instance Method Summary collapse
- #column(offset, known_line = nil) ⇒ Object
-
#initialize(string) ⇒ Source
constructor
A new instance of Source.
- #line(offset) ⇒ Object
- #point(offset) ⇒ Object
-
#trim(offset) ⇒ Object
Trim trailing whitespace-only and comment-only lines from the given offset.
- #trim_comments(offset) ⇒ Object
Constructor Details
#initialize(string) ⇒ Source
Returns a new instance of Source.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/psych/pure.rb', line 47 def initialize(string) @string = string offsets = [0] @last_line_index = 0 @last_line_offset = 0 idx = 0 while (found = string.index("\n", idx)) offsets << (idx = found + 1) end offsets << string.bytesize if offsets.last != string.bytesize @line_offsets = offsets end |
Instance Attribute Details
#trim_line ⇒ Object (readonly)
The line index computed by the most recent call to #trim.
45 46 47 |
# File 'lib/psych/pure.rb', line 45 def trim_line @trim_line end |
Instance Method Details
#column(offset, known_line = nil) ⇒ Object
130 131 132 |
# File 'lib/psych/pure.rb', line 130 def column(offset, known_line = nil) offset - @line_offsets[known_line || line(offset)] end |
#line(offset) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/psych/pure.rb', line 102 def line(offset) # Fast path: linear scan forward from the last lookup position. # The parser generally moves forward through the input, so this # avoids the O(log n) bsearch in the common case. cached = @last_line_index offsets = @line_offsets if offset >= @last_line_offset max = offsets.size - 1 while cached < max && offsets[cached + 1] <= offset cached += 1 end @last_line_index = cached @last_line_offset = offsets[cached] cached else # Backward seek — linear scan backward from cached position while cached > 0 && offsets[cached] > offset cached -= 1 end @last_line_index = cached @last_line_offset = offsets[cached] cached end end |
#point(offset) ⇒ Object
134 135 136 |
# File 'lib/psych/pure.rb', line 134 def point(offset) "line #{line(offset) + 1} column #{column(offset)}" end |
#trim(offset) ⇒ Object
Trim trailing whitespace-only and comment-only lines from the given offset. After calling, @trim_line holds the line index of the returned offset so callers can avoid a redundant line() lookup.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/psych/pure.rb', line 65 def trim(offset) offsets = @line_offsets string = @string l = line(offset) while l != 0 && offset == offsets[l] prev_start = offsets[l - 1] prev_end = offsets[l] - 1 idx = prev_start idx += 1 while idx < prev_end && string.getbyte(idx) == 0x20 # space break unless idx >= prev_end || string.getbyte(idx) == 0x23 # # offset = prev_start l -= 1 end @trim_line = l offset end |
#trim_comments(offset) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/psych/pure.rb', line 84 def trim_comments(offset) offsets = @line_offsets string = @string l = line(offset) while l != 0 && offset == offsets[l] prev_start = offsets[l - 1] prev_end = offsets[l] - 1 idx = prev_start idx += 1 while idx < prev_end && string.getbyte(idx) == 0x20 # space break unless idx < prev_end && string.getbyte(idx) == 0x23 # # offset = prev_start l -= 1 end offset end |