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
30
# 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)



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

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



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

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



201
202
203
204
205
206
# File 'lib/nio/bytebuffer.rb', line 201

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)


211
212
213
# File 'lib/nio/bytebuffer.rb', line 211

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



169
170
171
172
173
174
# File 'lib/nio/bytebuffer.rb', line 169

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

#full?true, false

Does the ByteBuffer have any space remaining?

Returns:

  • (true, false)


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

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:



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

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



218
219
220
221
222
223
224
225
226
227
# File 'lib/nio/bytebuffer.rb', line 218

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



184
185
186
187
# File 'lib/nio/bytebuffer.rb', line 184

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:



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

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:



140
141
142
143
144
145
146
147
148
149
# File 'lib/nio/bytebuffer.rb', line 140

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



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

def remaining
  @limit - @position
end

#resetObject

Reset position to the previously marked location

Raises:



192
193
194
195
196
197
# File 'lib/nio/bytebuffer.rb', line 192

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



177
178
179
180
181
# File 'lib/nio/bytebuffer.rb', line 177

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:



157
158
159
160
161
162
163
164
165
166
# File 'lib/nio/bytebuffer.rb', line 157

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