class Bzip2::FFI::IO

{IO} is a base class providing common functionality for the {Reader} and {Writer} subclasses.

Holds a reference to an underlying IO-like stream representing the bzip2 compressed data to be read from or written to.

Attributes

io[R]

The underlying compressed IO-like instance.

Public Class Methods

new(io, options = {}) click to toggle source

Initializes a new {IO} instance with an underlying compressed IO-like instance and options Hash.

binmode is called on io if io responds to binmode.

A single :autoclose option is supported. Set :autoclose to true to close the underlying compressed IO-like instance when {#close} is called.

@param io [Object] An IO-like object that represents the compressed data. @param options [Hash] Optional parameters (:autoclose). @raise [ArgumentError] If io is nil.

# File lib/bzip2/ffi/io.rb, line 200
def initialize(io, options = {})
  raise ArgumentError, 'io is required' unless io

  @io = io
  @io.binmode if @io.respond_to?(:binmode)

  @autoclose = !!options[:autoclose]

  @stream = Libbz2::BzStream.new
end

Protected Class Methods

open(io_or_proc, options = {}) { |bz_io| ... } click to toggle source

If no block is provided, returns a new {IO}. If a block is provided, a new {IO} is created and yielded to the block. After the block has executed, the {IO} is closed and the result of the block is returned.

If io_or_proc is a Proc, it is called to obtain an IO-like instance to pass to new. Otherwise io_or_proc is passed directly to new.

@param io_or_proc [Object] An IO-like object or a Proc that returns an IO-like object when called. @param options [Hash] Options to pass to new. @yield [io] If a block is given, it is yielded to. @yieldparam io [IO] The new {IO} instance. @yieldresult [Object] A result to be returned as the result of {open}. @return [Object] The result of the block if a block is given, otherwise the new {IO} instance.

# File lib/bzip2/ffi/io.rb, line 33
def open(io_or_proc, options = {})
  if io_or_proc.kind_of?(Proc)
    io = io_or_proc.call
    begin
      bz_io = new(io, options)
    rescue
      io.close if io.respond_to?(:close)
      raise
    end
  else
    bz_io = new(io_or_proc, options)
  end

  if block_given?
    begin
      yield bz_io
    ensure
      bz_io.close unless bz_io.closed?
    end
  else
    bz_io
  end
end
open_bzip_file(path, mode) click to toggle source

Opens and returns a bzip file using the specified mode. The system is advised that the file will be accessed once sequentially.

@param path [String] The path to open. @param mode [String] The file open mode to use. @return [File] An open File object for path opened using mode.

# File lib/bzip2/ffi/io.rb, line 63
def open_bzip_file(path, mode)
  io = File.open(path, mode)

  begin
    after_open_file(io)
  rescue
    io.close
    raise
  end

  io
end

Private Class Methods

after_open_file(io) click to toggle source

Advises the system that an ::IO will be accessed once sequentially.

@param io [::IO] An ::IO instance to advise.

# File lib/bzip2/ffi/io.rb, line 81
def after_open_file(io)
  # JRuby 1.7.18 doesn't have a File#advise method (in any mode).
  if io.respond_to?(:advise)
    io.advise(:sequential)
    io.advise(:noreuse)
  end
end

Public Instance Methods

autoclose=(autoclose) click to toggle source

Sets whether the underlying compressed IO-like instance should be closed when {#close} is called (true) or left open (false).

@param autoclose [Boolean] true if the underlying compressed IO instance should be closed when {#close} is called, or false if it should be left open. @raise [IOError] If the {IO} instance has been closed.

# File lib/bzip2/ffi/io.rb, line 109
def autoclose=(autoclose)
  check_closed
  @autoclose = !!autoclose
end
autoclose?() click to toggle source

Returns true if the underlying compressed IO-like instance will be closed when {#close} is called, otherwise false.

@return [Boolean] true if the underlying compressed IO-like instance will be closed when {#close} is closed, otherwise false. @raise [IOError] If the {IO} instance has been closed.

# File lib/bzip2/ffi/io.rb, line 97
def autoclose?
  check_closed
  @autoclose
end
binmode() click to toggle source

Puts the {IO} instance into binary mode.

Note that {IO} and subclasses always operate in binary mode, so calling binmode has no effect.

@return [IO] self. @raise [IOError] If the {IO} instance has been closed.

# File lib/bzip2/ffi/io.rb, line 131
def binmode
  check_closed
  self
end
binmode?() click to toggle source

Returns true to indicate that the {IO} instance is operating in binary mode (as is always the case).

@return [Boolean] true. @raise [IOError] If the {IO} instance has been closed.

# File lib/bzip2/ffi/io.rb, line 119
def binmode?
  check_closed
  true
end
close() click to toggle source

Closes the {IO} instance.

If {#autoclose?} is true and the underlying compressed IO-like instance responds to close, it will also be closed.

@return [NilClass] nil. @raise [IOError] If the {IO} instance has already been closed.

# File lib/bzip2/ffi/io.rb, line 143
def close
  check_closed
  @io.close if autoclose? && @io.respond_to?(:close)
  @stream = nil
end
closed?() click to toggle source

Indicates whether the {IO} instance has been closed by calling {#close}.

@return [Boolean] true if the {IO} instance has been closed, otherwise false.

# File lib/bzip2/ffi/io.rb, line 153
def closed?
  !@stream
end
external_encoding() click to toggle source

Returns the Encoding object that represents the encoding of data prior to being compressed or after being decompressed.

No character conversion is performed, so external_encoding always returns Encoding::ASCII_8BIT (also known as Encoding::BINARY).

@return [Encoding] Encoding::ASCII_8BIT. @raise [IOError] If the {IO} instance has been closed.

# File lib/bzip2/ffi/io.rb, line 165
def external_encoding
  check_closed
  Encoding::ASCII_8BIT
end
internal_encoding() click to toggle source

The internal encoding for character conversions.

No character conversion is performed, so internal_encoding always returns Encoding::ASCII_8BIT (also known as Encoding::BINARY).

@return [Encoding] Encoding::ASCII_8BIT. @raise [IOError] If the IO has been closed.

# File lib/bzip2/ffi/io.rb, line 177
def internal_encoding
  check_closed
  Encoding::ASCII_8BIT
end

Protected Instance Methods

check_closed() click to toggle source

Raises an IOError if {#close} has been called to close the {IO} instance.

@raise [IOError] If the {IO} instance has been closed.

# File lib/bzip2/ffi/io.rb, line 226
def check_closed
  raise IOError, 'closed stream' if closed?
end
check_error(res) click to toggle source

Checks a return code from a libbz2 function. If it is greater than or equal to 0 (success), the return code is returned. If it is less than zero (an error), the appropriate {Error::Bzip2Error} sub-class is raised.

@param res [Integer] The result of a call to a libbz2 function. @return [Integer] res if res is greater than or equal to 0. @raise [Error::Bzip2Error] if res is less than 0.

# File lib/bzip2/ffi/io.rb, line 238
def check_error(res)
  return res if res >= 0

  error_class = case res
    when Libbz2::BZ_SEQUENCE_ERROR
      Error::SequenceError
    when Libbz2::BZ_PARAM_ERROR
      Error::ParamError
    when Libbz2::BZ_MEM_ERROR
      Error::MemoryError
    when Libbz2::BZ_DATA_ERROR
      Error::DataError
    when Libbz2::BZ_DATA_ERROR_MAGIC
      Error::MagicDataError
    when Libbz2::BZ_CONFIG_ERROR
      Error::ConfigError
    else
      raise Error::UnexpectedError.new(res)
  end

  raise error_class.new
end
stream() click to toggle source

Returns the {Libbz2::BzStream} instance being used to interface with libbz2.

@return [Libbz2::BzStream] The {Libbz2::BzStream} instance being used to interface with libbz2. @raise [IOError] If the {IO} instance has been closed.

# File lib/bzip2/ffi/io.rb, line 217
def stream
  check_closed
  @stream
end