Class: ZipTricks::RemoteIO
- Inherits:
-
Object
- Object
- ZipTricks::RemoteIO
- 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 FileReader
central directory parser. Effectively we substitute an IO object
for an object that fetches parts of the remote file over HTTP using
Range:
headers. TheRemoteIO
acts as an adapter between an object that performs the actual fetches over HTTP and an object that expects a handful of IO methods to be available.
Instance Method Summary collapse
-
#initialize(fetcher = :NOT_SET) ⇒ RemoteIO
constructor
A new instance of RemoteIO.
-
#read(n_bytes = nil) ⇒ String
Emulates IO#read, but requires the number of bytes to read The method will raise if the number of bytes read from remote does not match the number requested.
-
#seek(offset, mode = IO::SEEK_SET) ⇒ Object
Emulates IO#seek.
-
#size ⇒ Fixnum
Emulates IO#size.
-
#tell ⇒ Fixnum
Returns the current pointer position within the IO.
Constructor Details
#initialize(fetcher = :NOT_SET) ⇒ RemoteIO
Returns a new instance of RemoteIO.
10 11 12 13 14 |
# File 'lib/zip_tricks/remote_io.rb', line 10 def initialize(fetcher = :NOT_SET) @pos = 0 @fetcher = fetcher @remote_size = false end |
Instance Method Details
#read(n_bytes = nil) ⇒ String
Emulates IO#read, but requires the number of bytes to read
The method will raise if the number of bytes read from remote does
not match the number requested. The read will be limited to the
size of the remote resource relative to the current offset in the IO,
so if you are at offset 0 in the IO of size 10, doing a read(20)
will only return you 10 bytes of result, and not raise any exceptions.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/zip_tricks/remote_io.rb', line 40 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
17 18 19 20 21 22 |
# File 'lib/zip_tricks/remote_io.rb', line 17 def seek(offset, mode = IO::SEEK_SET) raise "Unsupported read mode #{mode}" unless mode == IO::SEEK_SET @remote_size ||= request_object_size @pos = clamp(0, offset, @remote_size) 0 # always return 0! end |
#size ⇒ Fixnum
Emulates IO#size.
27 28 29 |
# File 'lib/zip_tricks/remote_io.rb', line 27 def size @remote_size ||= request_object_size end |
#tell ⇒ Fixnum
Returns the current pointer position within the IO
64 65 66 |
# File 'lib/zip_tricks/remote_io.rb', line 64 def tell @pos end |