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

Returns a new instance of FileInput.



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

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.



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

def column
  @column
end

#ioIO (readonly)

Returns:

  • (IO)


13
14
15
# File 'lib/stupidedi/reader/input/file_input.rb', line 13

def io
  @io
end

#lineInteger (readonly)

(see AbstractInput#line)

Returns:



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

def line
  @line
end

#offsetObject (readonly)

Returns the value of attribute offset.



24
25
26
# File 'lib/stupidedi/reader/input/file_input.rb', line 24

def offset
  @offset
end

#pathObject (readonly)

Returns the value of attribute path.



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

def path
  @path
end

Instance Method Details

#at(n) ⇒ String

Returns:

Raises:

  • (ArgumentError)


56
57
58
59
60
61
# File 'lib/stupidedi/reader/input/file_input.rb', line 56

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

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

#defined_at?(n) ⇒ Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/stupidedi/reader/input/file_input.rb', line 111

def defined_at?(n)
  n < @size
end

#drop(n) ⇒ AbstractInput

Advance the cursor forward ‘n` elements

Parameters:

  • n (Integer)

    the number of elements to advance (‘n >= 0`)

Returns:



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

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

Returns:

  • (Boolean)


116
117
118
# File 'lib/stupidedi/reader/input/file_input.rb', line 116

def empty?
  @io.eof?
end

#index(value) ⇒ Integer

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

Parameters:

  • element (Object)

    the element to find in the input

Returns:

  • (Integer)
  • nil if ‘element` is not present in the input



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

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

Returns:



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

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

#pretty_print(q) ⇒ void

This method returns an undefined value.



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

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

Returns:



46
47
48
49
50
51
52
# File 'lib/stupidedi/reader/input/file_input.rb', line 46

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