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.



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)

Returns:

  • (IO)


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

def io
  @io
end

#lineInteger (readonly)

(see AbstractInput#line)

Returns:

  • (Integer)


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

Returns:

  • (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

Returns:

  • (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

Parameters:

  • n (Integer)

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

Returns:



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

Returns:

  • (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`

Parameters:

  • element (Object)

    the element to find in the input

Returns:

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



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

Returns:

  • (String)


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

This method returns an undefined value.



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

Returns:

  • (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