class ByteBuffer::Buffer

Constants

DEFAULT_PREALLOC_SIZE

Public Class Methods

new(p1 = v1, p2 = v2) click to toggle source
VALUE
rb_byte_buffer_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE str, prealloc_size;

    rb_scan_args(argc, argv, "02", &str, &prealloc_size);

    if (!NIL_P(prealloc_size)) {
        buffer_t *b;
        long len;

        Check_Type(prealloc_size, T_FIXNUM);
        len = FIX2LONG(prealloc_size);
        if (len < 0) rb_raise(rb_eRangeError, "prealloc size can't be negative");
        TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);

        if ((size_t)len > b->size) {
            if (b->b_ptr != b->embedded_buffer) xfree(b->b_ptr);
            b->b_ptr = ALLOC_N(char, len);
            b->size = len;
            b->read_pos = b->write_pos = 0;
        }
    }

    if (!NIL_P(str))
        rb_byte_buffer_append(self, str);

    return self;
}

Public Instance Methods

<<(p1)
Alias for: append
==(other)
Alias for: eql?
append(p1) click to toggle source
VALUE
rb_byte_buffer_append(VALUE self, VALUE str)
{
    char     *c_str;
    size_t   len;
    buffer_t *b;

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);

    if (CLASS_OF(str) == rb_cString) {
        c_str = RSTRING_PTR(str);
        len   = RSTRING_LEN(str);
    } else if (rb_cBuffer && rb_obj_is_kind_of(str, rb_cBuffer)) {
        buffer_t *other_b;
        TypedData_Get_Struct(str, buffer_t, &buffer_data_type, other_b);
        c_str = READ_PTR(other_b);
        len   = READ_SIZE(other_b);
    } else {
        VALUE s = rb_funcall(str, rb_intern("to_s"), 0, 0);
        c_str = RSTRING_PTR(s);
        len   = RSTRING_LEN(s);
    }

    ENSURE_WRITE_CAPACITY(b, len);
    memcpy(WRITE_PTR(b), c_str, len);
    b->write_pos += len;

    return self;
}
Also aliased as: <<
append_byte(p1) click to toggle source
VALUE
rb_byte_buffer_append_byte(VALUE self, VALUE i)
{
    buffer_t *b;
    int32_t i32 = value_to_int32(i);
    int8_t i8 = (int8_t)i32;

    if (i32 > 0xFF || -i32 > 0x80)
        rb_raise(rb_eRangeError, "Number %d doesn't fit into byte", i32);

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_WRITE_CAPACITY(b, 1);
    *((int8_t*)WRITE_PTR(b)) = i8;
    b->write_pos += 1;

    return self;
}
append_byte_array(p1) click to toggle source
VALUE
rb_byte_buffer_append_byte_array(VALUE self, VALUE maybe_ary)
{
    VALUE ary = rb_check_array_type(maybe_ary);
    VALUE *ary_ptr;
    long len, i;
    buffer_t *b;

    if (NIL_P(ary))
        rb_raise(rb_eTypeError, "expected Array, got %s", rb_obj_classname(maybe_ary));

    len = RARRAY_LEN(ary);
    ary_ptr = RARRAY_PTR(ary);

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_WRITE_CAPACITY(b, len);
    for (i = 0; i < RARRAY_LEN(ary); ++i) {
        VALUE n = ary_ptr[i];
        int32_t i32 = value_to_int32(n);
        int8_t i8 = (int8_t)i32;

        if (i32 > 0xFF || -i32 > 0x80)
            rb_raise(rb_eRangeError, "Number %d doesn't fit into byte", i32);

        ((int8_t*)WRITE_PTR(b))[i] = i8;
    }

    b->write_pos += len;

    return self;
}
append_double(p1) click to toggle source
VALUE
rb_byte_buffer_append_double(VALUE self, VALUE i)
{
    buffer_t *b;
    union {double d; uint64_t i64;} ucast;

    ucast.d = value_to_dbl(i);
    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_WRITE_CAPACITY(b, 8);
    ucast.i64 = htobe64(ucast.i64);
    *(int64_t*)WRITE_PTR(b) = ucast.i64;
    b->write_pos += 8;

    return self;
}
append_float(p1) click to toggle source
VALUE
rb_byte_buffer_append_float(VALUE self, VALUE i)
{
    buffer_t *b;
    union {float f; uint32_t i32;} ucast;

    ucast.f = (float)value_to_dbl(i);
    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_WRITE_CAPACITY(b, 4);
    ucast.i32 = htobe32(ucast.i32);
    *(int32_t*)WRITE_PTR(b) = ucast.i32;
    b->write_pos += 4;

    return self;
}
append_int(p1) click to toggle source
VALUE
rb_byte_buffer_append_int(VALUE self, VALUE i)
{
    buffer_t *b;
    int32_t i32 = value_to_int32(i);

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_WRITE_CAPACITY(b, 4);
    i32 = htobe32(i32);
    *((int32_t*)WRITE_PTR(b)) = i32;
    b->write_pos += 4;

    return self;
}
append_long(p1) click to toggle source
VALUE
rb_byte_buffer_append_long(VALUE self, VALUE i)
{
    buffer_t *b;
    int64_t i64 = value_to_int64(i);

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_WRITE_CAPACITY(b, 8);
    i64 = htobe64(i64);
    *((int64_t*)WRITE_PTR(b)) = i64;
    b->write_pos += 8;

    return self;
}
append_short(p1) click to toggle source
VALUE
rb_byte_buffer_append_short(VALUE self, VALUE i)
{
    buffer_t *b;
    int32_t i32 = value_to_int32(i);
    int16_t i16 = (int16_t)i32;

    if (i32 > 0xFFFF || -i32 > 0x8000)
        rb_raise(rb_eRangeError, "Number %d doesn't fit into 2 bytes", i32);

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_WRITE_CAPACITY(b, 2);
    i16 = htobe16(i16);
    *((int16_t*)WRITE_PTR(b)) = i16;
    b->write_pos += 2;

    return self;
}
bytesize()
Alias for: length
capacity() click to toggle source
VALUE
rb_byte_buffer_capacity(VALUE self)
{
    buffer_t *b;

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);

    return UINT2NUM(b->size);
}
cheap_peek()
Alias for: to_str
discard(p1) click to toggle source
VALUE
rb_byte_buffer_discard(VALUE self, VALUE n)
{
    buffer_t *b;
    long len;

    Check_Type(n, T_FIXNUM);
    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    len = FIX2LONG(n);
    if (len < 0) rb_raise(rb_eRangeError, "Cannot discard a negative number of bytes");
    ENSURE_READ_CAPACITY(b, len);
    b->read_pos += len;

    return self;
}
dup() click to toggle source
# File lib/byte_buffer/buffer.rb, line 22
def dup
  self.class.new(self.to_str)
end
empty?() click to toggle source
# File lib/byte_buffer/buffer.rb, line 9
def empty?
  self.length == 0
end
eql?(other) click to toggle source
# File lib/byte_buffer/buffer.rb, line 13
def eql?(other)
  self.to_str.eql?(other.to_str)
end
Also aliased as: ==
hash() click to toggle source
# File lib/byte_buffer/buffer.rb, line 18
def hash
  to_str.hash
end
index(p1, p2 = v2) click to toggle source
VALUE
rb_byte_buffer_index(int argc, VALUE *argv, VALUE self)
{
    VALUE substr;
    VALUE voffset;
    size_t offset;
    buffer_t *b;

    rb_scan_args(argc, argv, "11", &substr, &voffset);
    Check_Type(substr, T_STRING);
    if (!NIL_P(voffset)) {
        long l = NUM2LONG(voffset);
        if (l < 0) rb_raise(rb_eRangeError, "offset can't be negative");
        offset = l;
    } else
        offset = 0;

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    if (offset >= READ_SIZE(b) || offset + RSTRING_LEN(substr) > READ_SIZE(b))
        return Qnil;
    else {
        char* pos = memmem(READ_PTR(b) + offset, READ_SIZE(b), RSTRING_PTR(substr), RSTRING_LEN(substr));
        if (pos)
            return UINT2NUM(pos - READ_PTR(b));
        else
            return Qnil;
    }
}
inspect() click to toggle source
VALUE
rb_byte_buffer_inspect(VALUE self)
{
    buffer_t *b;
    VALUE str;

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    str = rb_sprintf("#<%s:%p read_pos:%zu write_pos:%zu len:%zu capacity:%zu>",
        rb_obj_classname(self), (void*)self, b->read_pos, b->write_pos, READ_SIZE(b), b->size);

    return str;
}
length() click to toggle source
VALUE
rb_byte_buffer_length(VALUE self)
{
    buffer_t *b;

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);

    return UINT2NUM(READ_SIZE(b));
}
Also aliased as: size, bytesize
read(p1) click to toggle source
VALUE
rb_byte_buffer_read(VALUE self, VALUE n)
{
    buffer_t *b;
    long len;
    VALUE str;

    Check_Type(n, T_FIXNUM);
    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    len = FIX2LONG(n);
    if (len < 0) rb_raise(rb_eRangeError, "Cannot read a negative number of bytes");
    ENSURE_READ_CAPACITY(b, len);
    str = rb_str_new(READ_PTR(b), len);
    b->read_pos += len;

    return str;
}
read_byte(p1 = v1) click to toggle source
VALUE
rb_byte_buffer_read_byte(int argc, VALUE *argv, VALUE self)
{
    VALUE f_signed;
    buffer_t *b;
    uint8_t i8;

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

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_READ_CAPACITY(b, 1);
    i8 = *((uint8_t*)READ_PTR(b));
    b->read_pos += 1;

    if (RTEST(f_signed))
        return INT2NUM((int8_t)i8);
    else
        return UINT2NUM(i8);
}
read_byte_array(p1, p2 = v2) click to toggle source
VALUE
rb_byte_buffer_read_byte_array(int argc, VALUE *argv, VALUE self)
{
    buffer_t *b;
    VALUE n;
    VALUE f_signed;
    VALUE ary;
    long len, i;
    int b_signed;

    rb_scan_args(argc, argv, "11", &n, &f_signed);

    Check_Type(n, T_FIXNUM);
    len = FIX2LONG(n);
    if (len < 0) rb_raise(rb_eRangeError, "Cannot read a negative number of bytes");
    b_signed = RTEST(f_signed);

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_READ_CAPACITY(b, len);

    ary = rb_ary_new();
    for (i=0; i<len; ++i) {
        uint8_t i8 = *((uint8_t*)READ_PTR(b));
        b->read_pos += 1;

        if (b_signed)
            rb_ary_push(ary, INT2NUM((int8_t)i8));
        else
            rb_ary_push(ary, UINT2NUM(i8));
    }

    return ary;
}
read_double() click to toggle source
VALUE
rb_byte_buffer_read_double(VALUE self)
{
    buffer_t *b;
    union {uint64_t i64; double d;} ucast;

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_READ_CAPACITY(b, 8);
    ucast.i64 = be64toh(*(uint64_t*)READ_PTR(b));
    b->read_pos += 8;

    return DBL2NUM(ucast.d);
}
read_float() click to toggle source
VALUE
rb_byte_buffer_read_float(VALUE self)
{
    buffer_t *b;
    union {float d; uint32_t i32;} ucast;

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_READ_CAPACITY(b, 4);
    ucast.i32 = be32toh(*(uint32_t*)READ_PTR(b));
    b->read_pos += 4;

    return DBL2NUM((double)ucast.d);
}
read_int(p1 = v1) click to toggle source
VALUE
rb_byte_buffer_read_int(int argc, VALUE *argv, VALUE self)
{
    VALUE f_signed;
    buffer_t *b;
    uint32_t i32;

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

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_READ_CAPACITY(b, 4);
    i32 = be32toh(*((uint32_t*)READ_PTR(b)));
    b->read_pos += 4;

    if (RTEST(f_signed))
        return INT2NUM((int32_t)i32);
    else
        return UINT2NUM(i32);
}
read_long(p1 = v1) click to toggle source
VALUE
rb_byte_buffer_read_long(int argc, VALUE *argv, VALUE self)
{
    VALUE f_signed;
    buffer_t *b;
    uint64_t i64;

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

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_READ_CAPACITY(b, 8);
    i64 = be64toh(*((uint64_t*)READ_PTR(b)));
    b->read_pos += 8;

    if (RTEST(f_signed))
        return LONG2NUM((int64_t)i64);
    else
        return ULONG2NUM(i64);
}
read_short(p1 = v1) click to toggle source
VALUE
rb_byte_buffer_read_short(int argc, VALUE *argv, VALUE self)
{
    VALUE f_signed;
    buffer_t *b;
    uint16_t i16;

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

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    ENSURE_READ_CAPACITY(b, 2);
    i16 = be16toh(*((uint16_t*)READ_PTR(b)));
    b->read_pos += 2;

    if (RTEST(f_signed))
        return INT2NUM((int16_t)i16);
    else
        return UINT2NUM(i16);
}
size()
Alias for: length
to_s()
Alias for: to_str
to_str() click to toggle source
VALUE
rb_byte_buffer_to_str(VALUE self)
{
    buffer_t *b;
    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);

    return rb_str_new(READ_PTR(b), READ_SIZE(b));
}
Also aliased as: cheap_peek, to_s
update(p1, p2) click to toggle source
VALUE
rb_byte_buffer_update(VALUE self, VALUE location, VALUE bytes)
{
    long offset;
    long copy_bytes_len;
    buffer_t *b;

    Check_Type(location, T_FIXNUM);
    Check_Type(bytes, T_STRING);
    offset = NUM2LONG(location);
    if (offset < 0) rb_raise(rb_eRangeError, "location can't be negative");

    TypedData_Get_Struct(self, buffer_t, &buffer_data_type, b);
    if ((size_t)offset >= READ_SIZE(b))
        return self;

    copy_bytes_len = RSTRING_LEN(bytes);
    if ((size_t)(offset + copy_bytes_len) > READ_SIZE(b))
        copy_bytes_len = READ_SIZE(b) - offset;
    memcpy(READ_PTR(b) + offset, RSTRING_PTR(bytes), copy_bytes_len);

    return self;
}