Class: ZipTricks::RemoteIO

Inherits:
Object
  • Object
show all
Defined in:
lib/zip_tricks/remote_io.rb

Overview

An object that fakes just-enough of an IO to be dangerous

  • or, more precisely, to be useful as a source for the RubyZip central directory parser

Instance Method Summary collapse

Constructor Details

#initialize(fetcher = :NOT_SET) ⇒ RemoteIO

Returns a new instance of RemoteIO.

Parameters:

  • fetcher (#request_object_size, #request_range) (defaults to: :NOT_SET)

    an object that can fetch



7
8
9
10
11
# File 'lib/zip_tricks/remote_io.rb', line 7

def initialize(fetcher = :NOT_SET)
  @pos = 0
  @fetcher = fetcher
  @remote_size = false
end

Instance Method Details

#posFixnum

Returns the current pointer position within the IO. Not used by RubyZip but used in tests of our own

Returns:

  • (Fixnum)


54
55
56
# File 'lib/zip_tricks/remote_io.rb', line 54

def pos
  @pos
end

#read(n_bytes = nil) ⇒ Object

Emulates IO#read

Raises:

  • (ArgumentError)


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/zip_tricks/remote_io.rb', line 29

def read(n_bytes = nil)
  @remote_size ||= request_object_size

  # If the resource is empty there is nothing to read
  return nil if @remote_size.zero?

  maximum_avaialable = @remote_size - @pos
  n_bytes ||= maximum_avaialable # nil == read to the end of file
  return '' if n_bytes.zero?
  raise ArgumentError, "No negative reads(#{n_bytes})" if n_bytes < 0

  n_bytes = clamp(0, n_bytes, maximum_avaialable)

  read_n_bytes_from_remote(@pos, n_bytes).tap do |data|
    if data.bytesize != n_bytes
      raise "Remote read returned #{data.bytesize} bytes instead of #{n_bytes} as requested"
    end
    @pos = clamp(0, @pos + data.bytesize, @remote_size)
  end
end

#seek(offset, mode = IO::SEEK_SET) ⇒ Object

Emulates IO#seek



14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/zip_tricks/remote_io.rb', line 14

def seek(offset, mode = IO::SEEK_SET)
  case mode
    when IO::SEEK_SET
      @remote_size ||= request_object_size
      @pos = clamp(0, offset, @remote_size)
    when IO::SEEK_END
      @remote_size ||= request_object_size
      @pos = clamp(0, @remote_size + offset, @remote_size)
    else
      raise Errno::ENOTSUP, "Seek mode #{mode.inspect} not supported"
  end
  0 # always return 0!
end