class NIO::ByteBuffer

Efficient byte buffers for performant I/O operations

Constants

MarkUnsetError

Mark has not been set

OverflowError

Insufficient capacity in buffer

UnderflowError

Not enough data remaining in buffer

Public Class Methods

new(p1) click to toggle source
static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE capacity)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    buffer->capacity = NUM2INT(capacity);
    buffer->buffer = xmalloc(buffer->capacity);

    NIO_ByteBuffer_clear(self);

    return self;
}
new(capacity) click to toggle source

Create a new ByteBuffer, either with a specified capacity or populating it from a given string

@param capacity [Integer] size of buffer in bytes

@return [NIO::ByteBuffer]

# 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

Public Instance Methods

<<(p1) click to toggle source
static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string)
{
    long length;
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    StringValue(string);
    length = RSTRING_LEN(string);

    if (length > buffer->limit - buffer->position) {
        rb_raise(cNIO_ByteBuffer_OverflowError, "buffer is full");
    }

    memcpy(buffer->buffer + buffer->position, StringValuePtr(string), length);
    buffer->position += length;

    return self;
}
[](p1) click to toggle source
static VALUE NIO_ByteBuffer_fetch(VALUE self, VALUE index)
{
    int i;
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    i = NUM2INT(index);

    if (i < 0) {
        rb_raise(rb_eArgError, "negative index given");
    }

    if (i >= buffer->limit) {
        rb_raise(rb_eArgError, "specified index exceeds limit");
    }

    return INT2NUM(buffer->buffer[i]);
}
capacity() click to toggle source
static VALUE NIO_ByteBuffer_capacity(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    return INT2NUM(buffer->capacity);
}
Also aliased as: size
clear() click to toggle source
static VALUE NIO_ByteBuffer_clear(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    memset(buffer->buffer, 0, buffer->capacity);

    buffer->position = 0;
    buffer->limit = buffer->capacity;
    buffer->mark = MARK_UNSET;

    return self;
}
compact() click to toggle source
static VALUE NIO_ByteBuffer_compact(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    memmove(buffer->buffer, buffer->buffer + buffer->position, buffer->limit - buffer->position);
    buffer->position = buffer->limit - buffer->position;
    buffer->limit = buffer->capacity;

    return self;
}
each() click to toggle source
static VALUE NIO_ByteBuffer_each(VALUE self)
{
    int i;
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    if (rb_block_given_p()) {
        for (i = 0; i < buffer->limit; i++) {
            rb_yield(INT2NUM(buffer->buffer[i]));
        }
    } else {
        rb_raise(rb_eArgError, "no block given");
    }

    return self;
}
flip() click to toggle source
static VALUE NIO_ByteBuffer_flip(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    buffer->limit = buffer->position;
    buffer->position = 0;
    buffer->mark = MARK_UNSET;

    return self;
}
full?() click to toggle source
static VALUE NIO_ByteBuffer_full(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    return buffer->position == buffer->limit ? Qtrue : Qfalse;
}
get(p1 = v1) click to toggle source
static VALUE NIO_ByteBuffer_get(int argc, VALUE *argv, VALUE self)
{
    int len;
    VALUE length, result;
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    rb_scan_args(argc, argv, "01", &length);

    if (length == Qnil) {
        len = buffer->limit - buffer->position;
    } else {
        len = NUM2INT(length);
    }

    if (len < 0) {
        rb_raise(rb_eArgError, "negative length given");
    }

    if (len > buffer->limit - buffer->position) {
        rb_raise(cNIO_ByteBuffer_UnderflowError, "not enough data in buffer");
    }

    result = rb_str_new(buffer->buffer + buffer->position, len);
    buffer->position += len;

    return result;
}
inspect() click to toggle source
static VALUE NIO_ByteBuffer_inspect(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    return rb_sprintf(
        "#<%s:%p @position=%d @limit=%d @capacity=%d>",
        rb_class2name(CLASS_OF(self)),
        (void *)self,
        buffer->position,
        buffer->limit,
        buffer->capacity);
}
limit() click to toggle source
static VALUE NIO_ByteBuffer_get_limit(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    return INT2NUM(buffer->limit);
}
limit=(p1) click to toggle source
static VALUE NIO_ByteBuffer_set_limit(VALUE self, VALUE new_limit)
{
    int lim;
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    lim = NUM2INT(new_limit);

    if (lim < 0) {
        rb_raise(rb_eArgError, "negative limit given");
    }

    if (lim > buffer->capacity) {
        rb_raise(rb_eArgError, "specified limit exceeds capacity");
    }

    buffer->limit = lim;

    if (buffer->position > lim) {
        buffer->position = lim;
    }

    if (buffer->mark > lim) {
        buffer->mark = MARK_UNSET;
    }

    return new_limit;
}
mark() click to toggle source
static VALUE NIO_ByteBuffer_mark(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    buffer->mark = buffer->position;
    return self;
}
position() click to toggle source
static VALUE NIO_ByteBuffer_get_position(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    return INT2NUM(buffer->position);
}
position=(p1) click to toggle source
static VALUE NIO_ByteBuffer_set_position(VALUE self, VALUE new_position)
{
    int pos;
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    pos = NUM2INT(new_position);

    if (pos < 0) {
        rb_raise(rb_eArgError, "negative position given");
    }

    if (pos > buffer->limit) {
        rb_raise(rb_eArgError, "specified position exceeds limit");
    }

    buffer->position = pos;

    if (buffer->mark > buffer->position) {
        buffer->mark = MARK_UNSET;
    }

    return new_position;
}
put(str) click to toggle source

Add a String to the buffer

@param str [#to_str] data to add to the buffer

@raise [TypeError] given a non-string type @raise [NIO::ByteBuffer::OverflowError] buffer is full

@return [self]

# 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
Also aliased as: <<
read_from(p1) click to toggle source
static VALUE NIO_ByteBuffer_read_from(VALUE self, VALUE io)
{
    struct NIO_ByteBuffer *buffer;
    ssize_t nbytes, bytes_read;

    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    io = rb_convert_type(io, T_FILE, "IO", "to_io");
    io_set_nonblock(io);

    nbytes = buffer->limit - buffer->position;
    if (nbytes == 0) {
        rb_raise(cNIO_ByteBuffer_OverflowError, "buffer is full");
    }

    bytes_read = read(rb_io_descriptor(io), buffer->buffer + buffer->position, nbytes);

    if (bytes_read < 0) {
        if (errno == EAGAIN) {
            return INT2NUM(0);
        } else {
            rb_sys_fail("write");
        }
    }

    buffer->position += bytes_read;

    return SIZET2NUM(bytes_read);
}
remaining() click to toggle source
static VALUE NIO_ByteBuffer_remaining(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    return INT2NUM(buffer->limit - buffer->position);
}
reset() click to toggle source
static VALUE NIO_ByteBuffer_reset(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    if (buffer->mark < 0) {
        rb_raise(cNIO_ByteBuffer_MarkUnsetError, "mark has not been set");
    } else {
        buffer->position = buffer->mark;
    }

    return self;
}
rewind() click to toggle source
static VALUE NIO_ByteBuffer_rewind(VALUE self)
{
    struct NIO_ByteBuffer *buffer;
    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);

    buffer->position = 0;
    buffer->mark = MARK_UNSET;

    return self;
}
size()
Alias for: capacity
write_to(p1) click to toggle source
static VALUE NIO_ByteBuffer_write_to(VALUE self, VALUE io)
{
    struct NIO_ByteBuffer *buffer;
    ssize_t nbytes, bytes_written;

    Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
    io = rb_convert_type(io, T_FILE, "IO", "to_io");
    io_set_nonblock(io);

    nbytes = buffer->limit - buffer->position;
    if (nbytes == 0) {
        rb_raise(cNIO_ByteBuffer_UnderflowError, "no data remaining in buffer");
    }

    bytes_written = write(rb_io_descriptor(io), buffer->buffer + buffer->position, nbytes);

    if (bytes_written < 0) {
        if (errno == EAGAIN) {
            return INT2NUM(0);
        } else {
            rb_sys_fail("write");
        }
    }

    buffer->position += bytes_written;

    return SIZET2NUM(bytes_written);
}