class ADSP::Stream::Reader

ADSP::Stream::Reader class.

Constants

DEFAULT_SOURCE_BUFFER_LENGTH

Default source buffer length.

RawDecompressor

Current raw stream class.

Attributes

lineno[RW]

Current line for source data.

Public Class Methods

new(source_io, options = {}, *args) click to toggle source

Initializes stream using source_io native stream and options. Option: :external_encoding encoding name for destination data. Option: :internal_encoding encoding name for source data. Option: :transcode_options transcode options for data.

Calls superclass method ADSP::Stream::Abstract::new
# File lib/adsp/stream/reader.rb, line 28
def initialize(source_io, options = {}, *args)
  @options = options

  super source_io, *args

  initialize_source_buffer_length
  reset_io_remainder
  reset_need_to_flush

  @lineno = 0
end

Public Instance Methods

close() click to toggle source

Closes stream.

Calls superclass method ADSP::Stream::Abstract#close
# File lib/adsp/stream/reader.rb, line 105
def close
  raw_wrapper :close

  super
end
eof?() click to toggle source

Returns whether we are at the end of stream.

# File lib/adsp/stream/reader.rb, line 112
def eof?
  raise ValidateError, "io should be responsible to eof" unless @io.respond_to? :eof?

  empty? && @io.eof?
end
read(bytes_to_read = nil, out_buffer = nil) click to toggle source

Reads bytes_to_read bytes from stream. If out_buffer is defined than it will be used as output destination.

# File lib/adsp/stream/reader.rb, line 71
def read(bytes_to_read = nil, out_buffer = nil)
  Validation.validate_not_negative_integer bytes_to_read unless bytes_to_read.nil?
  Validation.validate_string out_buffer unless out_buffer.nil?

  raise ValidateError, "io should be responsible to read and eof" unless
    @io.respond_to?(:read) && @io.respond_to?(:eof?)

  unless bytes_to_read.nil?
    return ::String.new :encoding => ::Encoding::BINARY if bytes_to_read.zero?
    return nil if eof?

    append_io_data @io.read(@source_buffer_length) while @buffer.bytesize < bytes_to_read && !@io.eof?
    flush_io_data if @buffer.bytesize < bytes_to_read

    return read_bytes_from_buffer bytes_to_read, out_buffer
  end

  append_io_data @io.read(@source_buffer_length) until @io.eof?
  flush_io_data

  read_buffer out_buffer
end
read_nonblock(bytes_to_read, out_buffer = nil, *options) click to toggle source

Reads bytes_to_read bytes from stream. If out_buffer is defined than it will be used as output destination. options will be passed to native stream.

# File lib/adsp/stream/reader.rb, line 132
def read_nonblock(bytes_to_read, out_buffer = nil, *options)
  raise ValidateError, "io should be responsible to read nonblock" unless @io.respond_to? :read_nonblock

  read_more_nonblock(bytes_to_read, out_buffer) { @io.read_nonblock(@source_buffer_length, *options) }
end
readpartial(bytes_to_read, out_buffer = nil) click to toggle source

Reads bytes_to_read bytes from stream. If out_buffer is defined than it will be used as output destination. Raises ::EOFError when no data available.

# File lib/adsp/stream/reader.rb, line 123
def readpartial(bytes_to_read, out_buffer = nil)
  raise ValidateError, "io should be responsible to readpartial" unless @io.respond_to? :readpartial

  read_more_nonblock(bytes_to_read, out_buffer) { @io.readpartial @source_buffer_length }
end
rewind() click to toggle source

Resets stream.

Calls superclass method ADSP::Stream::Abstract#rewind
# File lib/adsp/stream/reader.rb, line 95
def rewind
  raw_wrapper :close

  reset_io_remainder
  reset_need_to_flush

  super
end

Protected Instance Methods

append_io_data(io_data) click to toggle source

Appends io_data from native stream to internal storage.

# File lib/adsp/stream/reader.rb, line 165
          def append_io_data(io_data)
  io_portion    = @io_remainder + io_data
  bytes_read    = raw_wrapper :read, io_portion
  @io_remainder = io_portion.byteslice bytes_read, io_portion.bytesize - bytes_read

  # Even empty io data may require flush.
  @need_to_flush = true
end
create_raw_stream() click to toggle source

Creates raw stream.

# File lib/adsp/stream/reader.rb, line 41
          def create_raw_stream
  self.class::RawDecompressor.new @options
end
empty?() click to toggle source

Returns whether stream is empty.

# File lib/adsp/stream/reader.rb, line 182
          def empty?
  !@need_to_flush && @buffer.bytesize.zero?
end
flush_io_data() click to toggle source

Triggers flush method for native stream.

# File lib/adsp/stream/reader.rb, line 175
          def flush_io_data
  raw_wrapper :flush

  @need_to_flush = false
end
initialize_source_buffer_length() click to toggle source

Initializes source buffer length.

# File lib/adsp/stream/reader.rb, line 46
          def initialize_source_buffer_length
  source_buffer_length = @options[:source_buffer_length]
  Validation.validate_not_negative_integer source_buffer_length unless source_buffer_length.nil?

  if source_buffer_length.nil? || source_buffer_length.zero?
    source_buffer_length = self.class::DEFAULT_SOURCE_BUFFER_LENGTH
  end

  @source_buffer_length = source_buffer_length
end
raw_wrapper(method_name, *args) click to toggle source

Wraps method_name for raw stream.

# File lib/adsp/stream/reader.rb, line 229
          def raw_wrapper(method_name, *args)
  @raw_stream.send(method_name, *args) { |portion| @buffer << portion }
end
read_buffer(out_buffer) click to toggle source

Reads data from buffer. If out_buffer is defined than it will be used as output destination.

# File lib/adsp/stream/reader.rb, line 202
          def read_buffer(out_buffer)
  result = @buffer
  reset_buffer
  @pos += result.bytesize

  result.force_encoding @external_encoding unless @external_encoding.nil?
  result = transcode_to_internal result

  result = out_buffer.replace result unless out_buffer.nil?
  result
end
read_bytes_from_buffer(bytes_to_read, out_buffer) click to toggle source

Reads bytes_to_read bytes from buffer. If out_buffer is defined than it will be used as output destination.

# File lib/adsp/stream/reader.rb, line 188
          def read_bytes_from_buffer(bytes_to_read, out_buffer)
  bytes_read = [@buffer.bytesize, bytes_to_read].min

  # Result uses buffer binary encoding.
  result   = @buffer.byteslice 0, bytes_read
  @buffer  = @buffer.byteslice bytes_read, @buffer.bytesize - bytes_read
  @pos    += bytes_read

  result = out_buffer.replace result unless out_buffer.nil?
  result
end
read_more_nonblock(bytes_to_read, out_buffer) { || ... } click to toggle source

Reads bytes_to_read bytes from stream. If out_buffer is defined than it will be used as output destination.

# File lib/adsp/stream/reader.rb, line 140
          def read_more_nonblock(bytes_to_read, out_buffer, &_block)
  Validation.validate_not_negative_integer bytes_to_read
  Validation.validate_string out_buffer unless out_buffer.nil?

  return ::String.new :encoding => ::Encoding::BINARY if bytes_to_read.zero?

  io_provided_eof_error = false

  if @buffer.bytesize < bytes_to_read
    begin
      append_io_data yield
    rescue ::EOFError
      io_provided_eof_error = true
    end
  end

  flush_io_data if @buffer.bytesize < bytes_to_read
  raise ::EOFError if empty? && io_provided_eof_error

  read_bytes_from_buffer bytes_to_read, out_buffer
end
reset_io_remainder() click to toggle source

Resets io remainder.

# File lib/adsp/stream/reader.rb, line 58
          def reset_io_remainder
  @io_remainder = ::String.new :encoding => ::Encoding::BINARY
end
reset_need_to_flush() click to toggle source

Resets need to flush flag.

# File lib/adsp/stream/reader.rb, line 63
          def reset_need_to_flush
  @need_to_flush = false
end
transcode_to_external(data) click to toggle source

Transcodes data to external encoding. We should be able to return data back to buffer. We won’t use any transcode options because transcoded data should be backward compatible.

# File lib/adsp/stream/reader.rb, line 223
          def transcode_to_external(data)
  data = data.encode @external_encoding unless @external_encoding.nil?
  data
end
transcode_to_internal(data) click to toggle source

Transcodes data to internal encoding.

# File lib/adsp/stream/reader.rb, line 215
          def transcode_to_internal(data)
  data = data.encode @internal_encoding, **@transcode_options unless @internal_encoding.nil?
  data
end