[Win32utils-devel] Who wants to take a stab at IO.foreach?

Daniel Berger djberg96 at gmail.com
Sat Oct 27 15:39:26 EDT 2007


Hi all,

Anyone want to help with a native IO.foreach?

I'm missing some of the critical logic here. This currently just does a 
straight BYTE_MAX data read, instead of a line by line data read, and 
doesn't deal with lines split between multiple reads.

I checked strtok into CVS (for windows-pr) if anyone wants to use that 
instead of String#split. It's in 'windows/msvcrt/string'.

require 'windows/file'
require 'windows/handle'
require 'windows/error'

class WinIO
    extend Windows::File
    extend Windows::Handle
    extend Windows::Error

    include Windows::File
    include Windows::Error

    MAX_READ = 20 # Small, for testing purposes

    def self.foreach(file, sep="\r\n")
       handle = CreateFile(
          file,
          FILE_READ_DATA,
          FILE_SHARE_READ,
          0,
          OPEN_EXISTING,
          0,
          0
       )

       if handle == INVALID_HANDLE_VALUE
          raise Error, get_last_error
       end

       buffer = 0.chr * MAX_READ
       nbytes = [0].pack('L')
       offset = 0

       olap = 0.chr * 20 # sizeof(OVERLAPPED)

       while bool = ReadFile(handle, buffer, buffer.size, nbytes, olap)
          error = GetLastError()

          if !bool && error == ERROR_INSUFFICIENT_BUFFER
             buffer = 0.chr * (buffer.size + buf_max)
             next
          end

          # TODO: Fix
          offset += MAX_READ
          yield buffer

          olap[8,4] = [offset].pack('L') # Bump the file pointer

          break if error == ERROR_HANDLE_EOF
       end

       unless CloseHandle(handle)
          raise RuntimeError, get_last_error
       end
    end
end

if $0 == __FILE__
    WinIO.foreach('some_file.txt'){ |l| p l }
end

Regards,

Dan


More information about the win32utils-devel mailing list