Class: NIO::ByteBuffer

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/nio/bytebuffer.rb,
ext/nio4r/bytebuffer.c

Overview

Efficient byte buffers for performant I/O operations

Defined Under Namespace

Classes: MarkUnsetError, OverflowError, UnderflowError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(capacity) ⇒ Object

Methods


25
26
27
28
29
# File 'lib/nio/bytebuffer.rb', line 25

def initialize(capacity)
  raise TypeError, "no implicit conversion of #{capacity.class} to Integer" unless capacity.is_a?(Integer)
  @capacity = capacity
  clear
end

Instance Attribute Details

#capacityObject (readonly)

Returns the value of attribute capacity


21
22
23
# File 'ext/nio4r/bytebuffer.c', line 21

def capacity
  @capacity
end

#limitObject

Returns the value of attribute limit


19
20
21
# File 'ext/nio4r/bytebuffer.c', line 19

def limit
  @limit
end

#positionObject

Returns the value of attribute position


17
18
19
# File 'ext/nio4r/bytebuffer.c', line 17

def position
  @position
end

Instance Method Details

#[](index) ⇒ Integer

Obtain the byte at a given index in the buffer as an Integer

Returns:

  • (Integer)

    byte at the given index

Raises:

  • (ArgumentError)

    index is invalid (either negative or larger than limit)


105
106
107
108
109
110
# File 'lib/nio/bytebuffer.rb', line 105

def [](index)
  raise ArgumentError, "negative index given" if index < 0
  raise ArgumentError, "specified index exceeds limit" if index >= @limit

  @buffer.bytes[index]
end

#clearObject

Clear the buffer, resetting it to the default state


32
33
34
35
36
37
38
39
# File 'lib/nio/bytebuffer.rb', line 32

def clear
  @buffer   = ("\0" * @capacity).force_encoding(Encoding::BINARY)
  @position = 0
  @limit    = @capacity
  @mark     = nil

  self
end

#compactObject

Move data between the position and limit to the beginning of the buffer Sets the position to the end of the moved data, and the limit to the capacity


197
198
199
200
201
202
# File 'lib/nio/bytebuffer.rb', line 197

def compact
  @buffer[0...(@limit - @position)] = @buffer[@position...@limit]
  @position = @limit - @position
  @limit = capacity
  self
end

#each(&block) ⇒ self

Iterate over the bytes in the buffer (as Integers)

Returns:

  • (self)

207
208
209
# File 'lib/nio/bytebuffer.rb', line 207

def each(&block)
  @buffer[0...@limit].each_byte(&block)
end

#flipObject

Set the buffer's current position as the limit and set the position to 0


166
167
168
169
170
171
# File 'lib/nio/bytebuffer.rb', line 166

def flip
  @limit = @position
  @position = 0
  @mark = nil
  self
end

#full?true, false

Does the ByteBuffer have any space remaining?

Returns:

  • (true, false)

81
82
83
# File 'lib/nio/bytebuffer.rb', line 81

def full?
  remaining.zero?
end

#get(length = remaining) ⇒ String

Obtain the requested number of bytes from the buffer, advancing the position. If no length is given, all remaining bytes are consumed.

Returns:

  • (String)

    bytes read from buffer

Raises:


91
92
93
94
95
96
97
98
# File 'lib/nio/bytebuffer.rb', line 91

def get(length = remaining)
  raise ArgumentError, "negative length given" if length < 0
  raise UnderflowError, "not enough data in buffer" if length > @limit - @position

  result = @buffer[@position...length]
  @position += length
  result
end

#inspectString

Inspect the state of the buffer

Returns:

  • (String)

    string describing the state of the buffer


214
215
216
217
218
219
220
221
222
223
# File 'lib/nio/bytebuffer.rb', line 214

def inspect
  format(
    "#<%s:0x%x @position=%d @limit=%d @capacity=%d>",
    self.class,
    object_id << 1,
    @position,
    @limit,
    @capacity
  )
end

#markObject

Mark a position to return to using the `#reset` method


181
182
183
184
# File 'lib/nio/bytebuffer.rb', line 181

def mark
  @mark = @position
  self
end

#put(str) ⇒ self Also known as: <<

Add a String to the buffer

Parameters:

  • str (#to_str)

    data to add to the buffer

Returns:

  • (self)

Raises:


120
121
122
123
124
125
126
127
128
# File 'lib/nio/bytebuffer.rb', line 120

def put(str)
  raise TypeError, "expected String, got #{str.class}" unless str.respond_to?(:to_str)
  str = str.to_str

  raise OverflowError, "buffer is full" if str.length > @limit - @position
  @buffer[@position...str.length] = str
  @position += str.length
  self
end

#read_from(io) ⇒ Integer

Perform a non-blocking read from the given IO object into the buffer Reads as much data as is immediately available and returns

Parameters:

  • Ruby (IO)

    IO object to read from

Returns:

  • (Integer)

    number of bytes read (0 if none were available)

Raises:


137
138
139
140
141
142
143
144
145
146
# File 'lib/nio/bytebuffer.rb', line 137

def read_from(io)
  nbytes = @limit - @position
  raise OverflowError, "buffer is full" if nbytes.zero?

  bytes_read = IO.try_convert(io).read_nonblock(nbytes, exception: false)
  return 0 if bytes_read == :wait_readable

  self << bytes_read
  bytes_read.length
end

#remainingInteger

Number of bytes remaining in the buffer before the limit

Returns:

  • (Integer)

    number of bytes remaining


74
75
76
# File 'lib/nio/bytebuffer.rb', line 74

def remaining
  @limit - @position
end

#resetObject

Reset position to the previously marked location

Raises:


189
190
191
192
193
# File 'lib/nio/bytebuffer.rb', line 189

def reset
  raise MarkUnsetError, "mark has not been set" unless @mark
  @position = @mark
  self
end

#rewindObject

Set the buffer's current position to 0, leaving the limit unchanged


174
175
176
177
178
# File 'lib/nio/bytebuffer.rb', line 174

def rewind
  @position = 0
  @mark = nil
  self
end

#sizeObject


21
# File 'ext/nio4r/bytebuffer.c', line 21

static VALUE NIO_ByteBuffer_capacity(VALUE self);

#write_to(io) ⇒ Integer

Perform a non-blocking write of the buffer's contents to the given I/O object Writes as much data as is immediately possible and returns

Parameters:

  • Ruby (IO)

    IO object to write to

Returns:

  • (Integer)

    number of bytes written (0 if the write would block)

Raises:


154
155
156
157
158
159
160
161
162
163
# File 'lib/nio/bytebuffer.rb', line 154

def write_to(io)
  nbytes = @limit - @position
  raise UnderflowError, "no data remaining in buffer" if nbytes.zero?

  bytes_written = IO.try_convert(io).write_nonblock(@buffer[@position...@limit], exception: false)
  return 0 if bytes_written == :wait_writable

  @position += bytes_written
  bytes_written
end