Class: Fibrio::Source

Inherits:
Object
  • Object
show all
Defined in:
lib/fibrio/source.rb

Constant Summary collapse

CHUNK_SIZE =
64 * 1024

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io, owns_io:, chunk_size: CHUNK_SIZE) ⇒ Source

Returns a new instance of Source.

Parameters:

  • io (IO, StringIO)
  • owns_io (Boolean)
  • chunk_size (Integer) (defaults to: CHUNK_SIZE)


38
39
40
41
42
43
44
45
46
47
48
# File 'lib/fibrio/source.rb', line 38

def initialize(io, owns_io:, chunk_size: CHUNK_SIZE)
  @io = io
  @owns_io = owns_io
  @chunk_size = chunk_size
  @buffer = +''.b
  @pos = 0
  @eof = false
  @position = 0
  @bytes_read = 0
  @next_char_calls = 0
end

Instance Attribute Details

#bytes_readObject (readonly)

Returns the value of attribute bytes_read.



9
10
11
# File 'lib/fibrio/source.rb', line 9

def bytes_read
  @bytes_read
end

#next_char_callsObject (readonly)

Returns the value of attribute next_char_calls.



9
10
11
# File 'lib/fibrio/source.rb', line 9

def next_char_calls
  @next_char_calls
end

#positionObject (readonly)

Returns the value of attribute position.



9
10
11
# File 'lib/fibrio/source.rb', line 9

def position
  @position
end

Class Method Details

.build(input, chunk_size: CHUNK_SIZE) ⇒ Source

Parameters:

  • input (String, IO, StringIO)
  • chunk_size (Integer) (defaults to: CHUNK_SIZE)

Returns:



14
15
16
17
18
19
20
21
22
23
# File 'lib/fibrio/source.rb', line 14

def self.build(input, chunk_size: CHUNK_SIZE)
  case input
  when IO, StringIO
    new(input, owns_io: true, chunk_size: chunk_size)
  when String
    build_from_string(input, chunk_size: chunk_size)
  else
    raise ArgumentError, "unsupported input: #{input.class}"
  end
end

Instance Method Details

#closevoid

This method returns an undefined value.



94
95
96
# File 'lib/fibrio/source.rb', line 94

def close
  @io.close if @owns_io && @io.respond_to?(:closed?) && !@io.closed?
end

#eof?Boolean

Returns:

  • (Boolean)


88
89
90
91
# File 'lib/fibrio/source.rb', line 88

def eof?
  ensure_buffer(1)
  @buffer.getbyte(@pos).nil?
end

#next_charString?

Returns next UTF-8 character and advances the source.

Returns:

  • (String, nil)

    next UTF-8 character and advances the source



65
66
67
68
69
70
71
72
73
74
# File 'lib/fibrio/source.rb', line 65

def next_char
  char = peek_char
  return nil unless char

  @pos += char.bytesize
  @position += char.bytesize
  @next_char_calls += 1
  compact_buffer
  char
end

#next_lineString?

Returns next line without trailing newline.

Returns:

  • (String, nil)

    next line without trailing newline



77
78
79
80
81
82
83
84
85
# File 'lib/fibrio/source.rb', line 77

def next_line
  loop do
    newline_index = @buffer.index("\n".b, @pos)
    return consume_line(newline_index) if newline_index
    return consume_remaining_line if @eof

    ensure_buffer(@buffer.bytesize - @pos + 1)
  end
end

#peek_charString?

Returns next UTF-8 character without consuming it.

Returns:

  • (String, nil)

    next UTF-8 character without consuming it



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/fibrio/source.rb', line 51

def peek_char
  ensure_buffer(1)
  first_byte = @buffer.getbyte(@pos)
  return nil unless first_byte

  char_length = utf8_char_length(first_byte)
  ensure_buffer(char_length)
  char_bytes = @buffer.byteslice(@pos, char_length)
  source_error('input ended in the middle of a UTF-8 character') if char_bytes.bytesize < char_length

  decode_utf8(char_bytes)
end