Module: External::Patches::WindowsIo

Defined in:
lib/external/patches/windows_io.rb

Overview

Ruby on Windows has problems with files larger than ~2 gigabytes. Sizes return as negative, and positions cannot be set beyond the max size of a long (2147483647 ~ 2GB = 2475636895). WindowsIo corrects both of these issues thanks in large part to a bit of code taken from ‘win32/file/stat’ (rubyforge.org/projects/win32utils/).

Constant Summary collapse

POSITION_MAX =

maximum size of long

2147483647

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(base) ⇒ Object



13
14
15
# File 'lib/external/patches/windows_io.rb', line 13

def self.extended(base)
  base.instance_variable_set("@pos", nil)
end

Instance Method Details

#posObject

Modified to handle positions past the 2Gb limit



18
19
20
# File 'lib/external/patches/windows_io.rb', line 18

def pos # :nodoc:
  @pos || super
end

#pos=(pos) ⇒ Object

Positions larger than the max value of a long cannot be directly given to the default pos=. This version incrementally seeks to positions beyond the maximum, if necessary.

Note: setting the position beyond the 2Gb limit requires the use of a sysseek statement. As such, errors will arise if you try to position an IO object that does not support this method (for example StringIO… but then what are you doing with a 2Gb StringIO anyhow?)



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

def pos=(pos)
  if pos < POSITION_MAX
    super(pos)
    @pos = nil
  elsif @pos != pos
    # note sysseek appears to be necessary here, rather than io.seek
    @pos = pos
  
    super(POSITION_MAX)
    pos -= POSITION_MAX
  
    while pos > POSITION_MAX
      pos -= POSITION_MAX
      self.sysseek(POSITION_MAX, ::IO::SEEK_CUR)
    end
  
    self.sysseek(pos, ::IO::SEEK_CUR)
  end
end