As a performance enhancement, try adding this:
# for ExternalIndex
if RUBY_PLATFORM.index('mswin').nil?
require 'inline'
inline do |builder|
#builder.include "<rubyio.h>"
# Array.new(str.length/frame_size) do |i|
# str[i*frame_size, frame_size].unpack(format)
# end
builder.c %Q{
static VALUE unpack(VALUE str)
{
char *p = RSTRING(str)->ptr;
int str_len = RSTRING(str)->len;
int frame_size = NUM2INT(rb_iv_get(self, "@frame_size"));
int frame = NUM2INT(rb_iv_get(self, "@frame"));
int i, j, times = str_len/frame_size;
VALUE fmt = rb_iv_get(self, "@format");
VALUE results, arr;
if(times <= 1)
return rb_funcall(str, rb_intern("unpack"), 1, fmt);
results = rb_ary_new();
i = 0;
while(i < times)
{
j = 0;
arr = rb_ary_new();
while(j < frame)
{
// no need to copy the data at *p,
// apparently the conversion can
// happen directly from the pointer
rb_ary_push(arr, UINT2NUM(*p));
p += 4;
++j;
}
rb_ary_push(results, arr);
++i;
}
return results;
}
}#File.read(File.dirname(__FILE__) + "/../../src/inline.c")
end
else
# on windows when it's not likely that the user has
# a compiler, include the precompiled binaries
# require ...
end