Class: Stupidedi::Reader::FileInput

Inherits:
AbstractInput show all
Defined in:
lib/stupidedi/reader/input/file_input.rb

Overview

Note:

This class is not thread-safe. If more than one ‘Thread` has access to the same instance, and they simultaneously call methods on that instance, the methods may produce incorrect results and the object might be left in an inconsistent state.

Querying the Position collapse

Instance Attribute Summary collapse

Querying the Position collapse

Reading the Input collapse

Advancing the Cursor collapse

Testing the Input collapse

Instance Method Summary collapse

Methods included from Inspect

#inspect

Constructor Details

#initialize(io, offset = 0, line = 1, column = 1, size = io.stat.size) ⇒ FileInput



18
19
20
21
# File 'lib/stupidedi/reader/input/file_input.rb', line 18

def initialize(io, offset = 0, line = 1, column = 1, size = io.stat.size)
  @io, @offset, @line, @column, @size =
    io, offset, line, column, size
end

Instance Attribute Details

#columnObject (readonly)

Returns the value of attribute column.



34
35
36
# File 'lib/stupidedi/reader/input/file_input.rb', line 34

def column
  @column
end

#ioIO (readonly)



16
17
18
# File 'lib/stupidedi/reader/input/file_input.rb', line 16

def io
  @io
end

#lineInteger (readonly)

(see AbstractInput#line)



31
32
33
# File 'lib/stupidedi/reader/input/file_input.rb', line 31

def line
  @line
end

#offsetObject (readonly)

Returns the value of attribute offset.



27
28
29
# File 'lib/stupidedi/reader/input/file_input.rb', line 27

def offset
  @offset
end

#pathObject (readonly)

Returns the value of attribute path.



37
38
39
# File 'lib/stupidedi/reader/input/file_input.rb', line 37

def path
  @path
end

Instance Method Details

#at(n) ⇒ String

Raises:

  • (ArgumentError)


59
60
61
62
63
64
# File 'lib/stupidedi/reader/input/file_input.rb', line 59

def at(n)
  raise ArgumentError, "n must be positive" unless n >= 0

  @io.seek(@offset + n)
  @io.read(1)
end

#defined_at?(n) ⇒ Boolean



114
115
116
# File 'lib/stupidedi/reader/input/file_input.rb', line 114

def defined_at?(n)
  n < @size
end

#drop(n) ⇒ AbstractInput

Advance the cursor forward ‘n` elements



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/stupidedi/reader/input/file_input.rb', line 88

def drop(n)
  raise ArgumentError, "n must be positive" unless n >= 0

  @io.seek(@offset)
  prefix = @io.read(n)
  suffix = @io

  length = prefix.length
  count  = prefix.count("\n")

  column = unless count.zero?
             length - prefix.rindex("\n")
           else
             @column + length
           end

  copy(:offset => @offset + length,
       :line   => @line + count,
       :column => column,
       :size   => @size - length)
end

#empty?Boolean



119
120
121
# File 'lib/stupidedi/reader/input/file_input.rb', line 119

def empty?
  @io.eof?
end

#index(value) ⇒ Integer

Returns the smallest ‘n`, where #at`(n)` == `element`



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/stupidedi/reader/input/file_input.rb', line 67

def index(value)
  @io.seek(@offset)
  length = value.length

  # We need to start with value != buffer, and this is a reasonable guess
  buffer = "\377" * length

  until @io.eof?
    buffer.slice!(0)
    buffer << @io.read(1)

    if buffer == value
      return @io.tell - @offset - length
    end
  end
end

#positionString

The file name, URI, etc that identifies the input stream



40
41
42
# File 'lib/stupidedi/reader/input/file_input.rb', line 40

def position
  Position.new(@offset, @line, @column, @io.path)
end

#pretty_print(q) ⇒ void



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/stupidedi/reader/input/file_input.rb', line 127

def pretty_print(q)
  q.text("FileInput")
  q.group(2, "(", ")") do
    preview = take(4)
    preview = if preview.empty?
                "EOF"
              elsif preview.length <= 3
                preview.inspect
              else
                (preview.take(3) << "...").inspect
              end

    q.text preview
    q.text " at line #{@line}, column #{@column}, offset #{@offset}, file #{File.basename(@io.path)}"
  end
end

#take(n) ⇒ String



49
50
51
52
53
54
55
# File 'lib/stupidedi/reader/input/file_input.rb', line 49

def take(n)
  @io.seek(@offset)

  # Calling @io.read with more than the number of available bytes will
  # return nil, so we have to calculate how many bytes remain
  @io.read((n <= @size) ? n : @size)
end