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



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

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)



112
113
114
115
116
117
# File 'lib/nio/bytebuffer.rb', line 112

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



39
40
41
42
43
44
45
46
# File 'lib/nio/bytebuffer.rb', line 39

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



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

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)


217
218
219
# File 'lib/nio/bytebuffer.rb', line 217

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



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

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

#full?true, false

Does the ByteBuffer have any space remaining?

Returns:

  • (true, false)


88
89
90
# File 'lib/nio/bytebuffer.rb', line 88

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:



98
99
100
101
102
103
104
105
# File 'lib/nio/bytebuffer.rb', line 98

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



224
225
226
227
228
229
230
231
232
233
# File 'lib/nio/bytebuffer.rb', line 224

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



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

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:



127
128
129
130
131
132
133
134
135
136
137
# File 'lib/nio/bytebuffer.rb', line 127

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:



146
147
148
149
150
151
152
153
154
155
# File 'lib/nio/bytebuffer.rb', line 146

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



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

def remaining
  @limit - @position
end

#resetObject

Reset position to the previously marked location

Raises:



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

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



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

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:



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

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