Class: IO::LikeHelpers::IOWrapper

Inherits:
DelegatedIO show all
Includes:
RubyFacts
Defined in:
lib/io/like_helpers/io_wrapper.rb

Overview

This class adapts Ruby’s IO implementation to the more primitive interface and behaviors expected by this library.

Constant Summary

Constants included from RubyFacts

RubyFacts::RBVER_LT_3_0, RubyFacts::RBVER_LT_3_0_4, RubyFacts::RBVER_LT_3_1, RubyFacts::RBVER_LT_3_2, RubyFacts::RBVER_LT_3_3, RubyFacts::RBVER_LT_3_4

Instance Method Summary collapse

Methods inherited from DelegatedIO

#advise, #autoclose=, #autoclose?, #close, #close_on_exec=, #close_on_exec?, create_finalizer, #fcntl, #fdatasync, #fileno, #fsync, #initialize, #inspect, #ioctl, #nonblock=, #nonblock?, #nread, #path, #pid, #stat, #to_io, #tty?

Methods inherited from AbstractIO

#advise, #close, #close_on_exec=, #close_on_exec?, #closed?, #fcntl, #fdatasync, #fileno, #fsync, #initialize, #ioctl, #nonblock, #nonblock=, #nonblock?, #nread, open, #path, #pid, #stat, #to_io, #tty?

Constructor Details

This class inherits a constructor from IO::LikeHelpers::DelegatedIO

Instance Method Details

#pread(length, offset, buffer: nil, buffer_offset: 0) ⇒ Integer, ...

Reads at most ‘length` bytes from the stream starting at `offset` without modifying the read position in the stream.

Note that a partial read will occur if the stream is in non-blocking mode and reading more bytes would block.

Raises:

  • (EOFError)

    when reading at the end of the stream

  • (IOError)

    if the stream is not readable



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/io/like_helpers/io_wrapper.rb', line 41

def pread(length, offset, buffer: nil, buffer_offset: 0)
  if ! buffer.nil?
    if buffer_offset < 0 || buffer_offset >= buffer.bytesize
      raise ArgumentError, 'buffer_offset is not a valid buffer index'
    end
    if buffer.bytesize - buffer_offset < length
      raise ArgumentError, 'length is greater than available buffer space'
    end
  end

  assert_readable

  content = delegate.pread(length, offset)
  return content if Symbol === content || buffer.nil?

  buffer[buffer_offset, content.bytesize] = content
  return content.bytesize
end

#pwrite(buffer, offset, length: buffer.bytesize) ⇒ Integer, ...

Writes at most ‘length` bytes to the stream starting at `offset` without modifying the write position in the stream.

Note that a partial write will occur if the stream is in non-blocking mode and writing more bytes would block.

Raises:

  • (IOError)

    if the stream is not writable



77
78
79
80
81
# File 'lib/io/like_helpers/io_wrapper.rb', line 77

def pwrite(buffer, offset, length: buffer.bytesize)
  assert_writable

  delegate.pwrite(buffer[0, length], offset)
end

#read(length, buffer: nil, buffer_offset: 0) ⇒ Integer, ...

Reads bytes from the stream.

Note that a partial read will occur if the stream is in non-blocking mode and reading more bytes would block.

Raises:

  • (EOFError)

    when reading at the end of the stream

  • (IOError)

    if the stream is not readable



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/io/like_helpers/io_wrapper.rb', line 102

def read(length, buffer: nil, buffer_offset: 0)
  if ! buffer.nil?
    if buffer_offset < 0 || buffer_offset >= buffer.bytesize
      raise ArgumentError, 'buffer_offset is not a valid buffer index'
    end
    if buffer.bytesize - buffer_offset < length
      raise ArgumentError, 'length is greater than available buffer space'
    end
  end

  assert_readable
  content = nonblock? ?
    read_nonblock(length) :
    delegate.sysread(length)

  return content if Symbol === content || buffer.nil?

  buffer[buffer_offset, content.bytesize] = content
  return content.bytesize
end

#readable?Boolean

Returns ‘true` if the stream is readable and `false` otherwise.



127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/io/like_helpers/io_wrapper.rb', line 127

def readable?
  return false if closed?
  return @readable if defined?(@readable) && ! @readable.nil?

  @readable =
    begin
      delegate.read(0)
      true
    rescue IOError
      false
    end
end

#ready?true, false

Returns whether or not the stream has input available.



145
146
147
148
149
# File 'lib/io/like_helpers/io_wrapper.rb', line 145

def ready?
  # This is a hack to work around the fact that IO#ready? returns an object
  # instance instead of true, contrary to documentation.
  !!super
end

#seek(amount, whence = IO::SEEK_SET) ⇒ Integer

Sets the current, unbuffered stream position to ‘amount` based on the setting of `whence`.

| ‘whence` | `amount` Interpretation | | ——– | ———————– | | `:CUR` or `IO::SEEK_CUR` | `amount` added to current stream position | | `:END` or `IO::SEEK_END` | `amount` added to end of stream position (`amount` will usually be negative here) | | `:SET` or `IO::SEEK_SET` | `amount` used as absolute position |

Raises:

  • (IOError)

    if the stream is closed

  • (Errno::ESPIPE)

    if the stream is not seekable



169
170
171
172
# File 'lib/io/like_helpers/io_wrapper.rb', line 169

def seek(amount, whence = IO::SEEK_SET)
  assert_open
  delegate.sysseek(amount, whence)
end

#wait(events, timeout = nil) ⇒ true, false

Waits until the stream becomes ready for at least 1 of the specified events.



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/io/like_helpers/io_wrapper.rb', line 184

def wait(events, timeout = nil)
  # The !! is a hack to work around the fact that IO#wait returns an object
  # instance instead of true, contrary to documentation.
  return !!super unless RBVER_LT_3_0

  # The rest of this implementation is for backward compatibility with the
  # IO#wait implamentation on Ruby versions prior to 3.0.
  #
  # TODO:
  # Remove this when Ruby 2.7 and below are no longer supported by this
  # library.
  assert_open
  mode =
    case events & (IO::READABLE | IO::WRITABLE)
    when IO::READABLE | IO::WRITABLE
      :read_write
    when IO::READABLE
      :read
    when IO::WRITABLE
      :write
    else
      return false
    end
  # The !! is a hack to work around the fact that IO#wait returns an object
  # instance instead of true, contrary to documentation.
  !!delegate.wait(timeout, mode)
end

#writable?Boolean

Returns ‘true` if the stream is writable and `false` otherwise.



236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/io/like_helpers/io_wrapper.rb', line 236

def writable?
  return false if closed?
  return @writable if defined?(@writable) && ! @writable.nil?

  @writable =
    begin
      delegate.write
      true
    rescue IOError
      false
    end
end

#write(buffer, length: buffer.bytesize) ⇒ Integer, ...

Writes bytes to the stream.

Note that a partial write will occur if the stream is in non-blocking mode and writing more bytes would block.

Raises:

  • (IOError)

    if the stream is not writable



226
227
228
229
230
# File 'lib/io/like_helpers/io_wrapper.rb', line 226

def write(buffer, length: buffer.bytesize)
  assert_writable
  return delegate.syswrite(buffer[0, length]) unless nonblock?
  write_nonblock(buffer[0, length])
end