>I just realized that the '[]=' is not implimented for Fixnum and Bignum.
>Add that to my feature request. :)
>
>There is no reason we just be able to write bitfields as well. I will
>try to write a patch if people (and Matz) like the feature. I have been
>wanting to learn Ruby internals.
I wrote the following code to create a BitVector type as an extension
some time ago. It was a quick hack, and I make no guarantees
that it even works with the latest verions...
Enjoy or dispose of as you see fit :-)
/\ndy
-------------------------------------------
#include "ruby.h"
#include <memory.h>
#include <stdio.h>
static ID numChars;
static ID numBits;
static ID storage;
static VALUE
bv_init(VALUE obj, VALUE size)
{
unsigned int size_in_chars;
unsigned char *arr;
unsigned int length;
size_in_chars = (NUM2INT(size) / sizeof(char)) +1;
rb_ivar_set(obj, numChars, size_in_chars);
rb_ivar_set(obj, numBits, size);
arr = malloc(size_in_chars);
memset(arr,0,size_in_chars);
rb_ivar_set(obj, storage, rb_str_new(arr, size_in_chars));
return obj;
}
static VALUE
bv_set_bit(VALUE obj, VALUE aNum, VALUE aVal)
{
unsigned int byte;
unsigned int bitnum;
VALUE st;
st = rb_ivar_get(obj, storage);
bitnum = NUM2INT(aNum);
byte = bitnum >> 3;
if (NUM2INT(aVal) != 0) {
RSTRING(st)->ptr[byte] |= 1 << (bitnum & 0x7);
} else {
RSTRING(st)->ptr[byte] &= ~(1 << (bitnum & 0x7));
}
return obj;
}
static VALUE
bv_get_size(VALUE obj)
{
return rb_ivar_get(obj, numChars);
}
static VALUE
bv_get_bit(VALUE obj, VALUE aNum)
{
unsigned int byte;
unsigned int bitnum;
VALUE st;
st = rb_ivar_get(obj, storage);
bitnum = NUM2INT(aNum);
byte = bitnum >> 3;
if (RSTRING(st)->ptr[byte] & (1 << (bitnum & 0x7)))
return INT2FIX(1);
return INT2FIX(0);
}
static VALUE cBitVector;
void Init_BitVector() {
numChars = rb_intern("numChars");
numBits = rb_intern("numBits");
storage = rb_intern("storage");
cBitVector = rb_define_class("BitVector", rb_cObject);
rb_define_method(cBitVector, "initialize", bv_init, 1);
rb_define_method(cBitVector, "[]", bv_get_bit, 1);
rb_define_method(cBitVector, "[]=", bv_set_bit, 2);
rb_define_method(cBitVector, "size", bv_get_size, 0);
}