From: Andrew Hunt Date: 2000-09-12T02:58:27+09:00 Subject: [ruby-talk:4858] Re: FEATURE REQUEST: Fixnum bitfields >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 #include 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); }