multibitnums-0.1.4/0000755000175000017500000000000011613412214014543 5ustar horinouthorinoutmultibitnums-0.1.4/ChangeLog0000644000175000017500000000145411613412114016320 0ustar horinouthorinoutTue Jul 26 2011 T Horinouchi * multibitnums-0.1.4 released (cvs tag multibitnums-0_1_4) Mon Jul 25 2011 T Horinouchi * multibitnums.c: changed to simply call rb_define_module("NumRu") (as is the case for other NumRu libraries such as RubyDCL) * test/test.rb, test/test2.rb: treatment for Ruby 1.9 (to call Integer#chr explicitly) Mon Jul 25 2011 T Horinouchi < Y Sasaki [dennou-ruby:003382] * test/test.rb, test/test2.rb: patch to conduct the unit test * multibitnums.c: patch for Ruby 1.9.2 Tue May 10 2005 T Horinouchi * multibitnums-0.1.3 released (cvs tag multibitnums-0_1_3) * LICENCE.txt: added (BSD 2-clause license) Fri May 13 2005 T Horinouchi * multibitnums-0.1.2 released (cvs tag multibitnums-0_1_2) * multibitnums.c: changed global variables such as mNumRu to file local multibitnums-0.1.4/LICENSE.txt0000644000175000017500000000326711562215704016406 0ustar horinouthorinoutMultibitnums is copyrighted free software by Takeshi Horinouchi and GFD Dennou Club (http://www.gfd-dennou.org/). Copyright 2011 (C) Takeshi Horinouchi and GFD Dennou Club (http://www.gfd-dennou.org/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY GFD DENNOU CLUB AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Takeshi Horinouchi and GFD Dennou Club. multibitnums-0.1.4/test/0000755000175000017500000000000011613412214015522 5ustar horinouthorinoutmultibitnums-0.1.4/test/test2.rb0000644000175000017500000000165711613227535017133 0ustar horinouthorinout#-*- mode: ruby; encoding: utf-8-unix -*-# require "test/unit" require "narray" require "numru/multibitnums" include NumRu class MultibitNumsTest2 < Test::Unit::TestCase def setup @nbit=10 @testdata1 = ' '*6 @testdata1[0] = 37.chr @testdata1[1] = 208.chr @testdata1[2] = 37.chr @testdata1[3] = 117.chr @testdata1[4] = 128.chr @testdata1[5] = 108.chr @expected1 = NArray[151,258,349,384] @testdata2 = ' '*6 @testdata2[0] = 15.chr @testdata2[1] = 131.chr @testdata2[2] = 240.chr @testdata2[3] = 252.chr @testdata2[4] = 64.chr @testdata2[5] = 16.chr @expected2 = NArray[62,63,63,64] end define_method("test_bigendian_unsigned_int2") do mb = MultiBitNums.new(@testdata1, @nbit) assert_equal @expected1, NArray.to_na( mb.to_int32str, 'int' ) mb = MultiBitNums.new(@testdata2, @nbit) assert_equal @expected2, NArray.to_na( mb.to_int32str, 'int' ) end end multibitnums-0.1.4/test/test.rb0000644000175000017500000000316311613227535017043 0ustar horinouthorinout#-*- mode: ruby; encoding: utf-8-unix -*-# require "test/unit" require "narray" require "numru/multibitnums" include NumRu class MultibitNumsTest1 < Test::Unit::TestCase def setup @testdata = ' '*10 for i in 0..9 @testdata[i] = 0x11.chr end @nbit2 = NArray.int(40).fill!(0) for i in 0..39 @nbit2[i] = 1 if i%2 == 1 end @nbit3 = NArray.int(26).fill!(0) for i in 0..25 @nbit3[i] = 0 if i%4 == 0 @nbit3[i] = 4 if i%4 == 1 @nbit3[i] = 2 if i%4 == 2 @nbit3[i] = 1 if i%4 == 3 end @nbit4 = NArray.int(20).fill!(1) @nbit5 = NArray.int(16) for i in 0..15 @nbit5[i] = 2 if i%4 ==0 @nbit5[i] = 4 if i%4 ==1 @nbit5[i] = 8 if i%4 ==2 @nbit5[i] = 17 if i%4 ==3 end @nbit6 = NArray.int(13) for i in 0..12 @nbit6[i] = 4 if i%2 == 0 @nbit6[i] = 17 if i%2 == 1 end @nbit7 = NArray.int(11) for i in 0..10 @nbit7[i] = 8 if i%4 == 0 @nbit7[i] = 68 if i%4 == 1 @nbit7[i] = 34 if i%4 == 2 @nbit7[i] = 17 if i%4 == 3 end @nbit8 = NArray.int(10).fill!(17) @nbit9 = NArray.int(8) for i in 0..7 @nbit9[i] = 34 if i%4 == 0 @nbit9[i] = 68 if i%4 == 1 @nbit9[i] = 136 if i%4 == 2 @nbit9[i] = 273 if i%4 == 3 end @nbit10 = NArray.int(8) for i in 0..7 @nbit10[i] = 68 if i%2 == 0 @nbit10[i] = 273 if i%2 == 1 end end define_method("test_bigedian_unsigned_int") do for nbit in 2..10 mb = MultiBitNums.new(@testdata, nbit) assert_equal eval("@nbit#{nbit}"), NArray.to_na( mb.to_int32str, 'int') end end end multibitnums-0.1.4/multibitnums.html0000644000175000017500000000503707515201314020175 0ustar horinouthorinout multibitnums.c

Class MultiBitNums

Class of multiple multi-bit data packed in a C string. The number of bits is fixed to an arbitrary value. For example, it can accommodate 11-bit integers.

Function overview

Integer encoding/decoding (so far only decoding has been implemented):

Class Methods

MultiBitNums.new( str, nbit [, nint] )

Creates a new object from a binary data (string) containing multi-bit segments.

ARGUMENTS

  • str (String): binary data containing multi-bit data
  • nbit (Integer): length in bits of each segments contained in str
  • nint (Integer, can be omitted): number of nbit-bit data in str. If omitted, derived automatically from the length of str.

RETURN VALUE

  • a MultiBitNums object

ERRORS

  • exception is raised if nint is too large for the length of str.

Instance Methods

to_int32str

Converts into a string containing binary data of 32-bit integers of the system. Useful with NArray.

ARGUMENTS

(none)

RETURN VALUE

  • a String (Its binary expression depends on the integer expression of the system).

ERRORS

EXAMPLE

mb = MultiBitNums.new(str, nbits)
require "narray"           # download it from RAA at www.ruby-lang.org
ary = NArray.to_na( mb, "int" )  # the data is read into a NArray ary
multibitnums-0.1.4/extconf.rb0000644000175000017500000000110607515307243016547 0ustar horinouthorinoutrequire "mkmf" def have_type(type, header=nil) printf "checking for %s... ", type STDOUT.flush src = <<"SRC" #include SRC unless header.nil? src << <<"SRC" #include <#{header}> SRC end r = try_link(src + <<"SRC") int main() { return 0; } int t() { #{type} a; return 0; } SRC unless r print "no\n" return false end $defs.push(format("-DHAVE_%s", type.upcase)) print "yes\n" return true end if have_header("sys/types.h") header = "sys/types.h" else header = nil end have_type("int32_t", header) create_makefile("numru/multibitnums") multibitnums-0.1.4/multibitnums.c0000644000175000017500000001336311613227535017463 0ustar horinouthorinout/* =begin = Class MultiBitNums Class of multiple multi-bit data packed in a C string. The number of bits is fixed to an arbitrary value. For example, it can accommodate 11-bit integers (but cannot a mixture of integers with different lengths). === Function overview Integer encoding/decoding (so far only decoding has been implemented): * Each segment of data is assumed to be multi-bit (fixed-length) unsigned integer in network byte order (big endian). * Note: integers of the system does not have to be big-endian (Only the binary data is interpreted as unsigned big-endian). ===Class Methods ---MultiBitNums.new( str, nbit [, nint] ) Creates a new object from a binary data (string) containing multi-bit segments. ARGUMENTS * str (String): binary data containing multi-bit data * nbit (Integer): length in bits of each segments contained in str * nint (Integer, can be omitted): number of nbit-bit data in str. If omitted, derived automatically from the length of str. RETURN VALUE * a MultiBitNums object ERRORS * exception is raised if nint is too large for the length of str. ===Instance Methods ---to_int32str Converts into a string containing binary data of 32-bit integers of the system. Useful with NArray. ARGUMENTS (none) RETURN VALUE * a String (Its binary expression depends on the integer expression of the system). ERRORS * exception is raised if nbit (see (())) is greater than 32. EXAMPLE mb = MultiBitNums.new(str, nbits) require "narray" # download it from RAA at www.ruby-lang.org ary = NArray.to_na( mb, "int" ) # the data is read into a NArray ary =end */ /* ruby.h for rb_raise */ #include "ruby.h" /* sys/typed.h : should be configured whether the system has this or not */ #include #ifndef HAVE_INT32_T typedef long int32_t; #endif #ifndef RSTRING_PTR #define RSTRNG_PTR(s) (RSTRING(s)->ptr) #endif #ifndef RSTRING_LEN #define RSTRING_LEN(a) (RSTRING(a)->len) #endif static VALUE mNumRu; static VALUE cMultiBitNums; struct MultiBitNums { unsigned char *ptr; /* holds data */ long len_ptr; /* length of ptr (in bytes) */ int nbit; /* length in bits of each integer in str */ long nint; /* number of data contained (<= len_str*8/static) */ }; static void mltbtnm_free(struct MultiBitNums *mbs) { xfree(mbs->ptr); mbs->len_ptr = 0; mbs->nbit = 0; mbs->nint = 0; xfree(mbs); } static VALUE mltbtnm_s_new(int argc, VALUE *argv, VALUE klass) { /* [ actual arguments --> */ VALUE str; VALUE nbit; VALUE nint; /* can be omitted */ /* <-- actual arguments ] */ struct MultiBitNums *mbs; long c_nint, nintmax; if (argc < 2 || argc >3){ rb_raise(rb_eArgError, "Usage: MultiBitNums.new(str, nbit [,nint]) -- nint is omittable"); } str = argv[0]; nbit = argv[1]; mbs = ALLOC(struct MultiBitNums); mbs->nbit = NUM2INT(nbit); mbs->len_ptr = RSTRING_LEN(str); mbs->ptr = ALLOC_N(char, mbs->len_ptr); memcpy( mbs->ptr, RSTRING_PTR(str), mbs->len_ptr); nintmax = ((mbs->len_ptr*8.0)/mbs->nbit + 0.1); if ( argc != 3 ){ mbs->nint = nintmax; } else { nint = argv[2]; c_nint = NUM2LONG(nint); if (c_nint > nintmax) { rb_raise(rb_eArgError, "nint is too long"); } else { mbs->nint = c_nint; } } return Data_Wrap_Struct(klass, 0, mltbtnm_free, mbs); } static int32_t * mltbtnm_read_int32(unsigned char *ptr, long len_ptr, int nbit, long *nint) /* unsigned char *ptr // holds data long len_ptr // length of ptr (in bytes) int nbit // number of bits long *nint // number of integers to read (if <= 0, determined // from len_ptr) */ { int32_t *result; long nintmax, i, n0, n1, k0, k1, w; long j, j2, nm; unsigned char cn[4],mk0,mb; nintmax = ((len_ptr*8.0)/nbit + 0.1); /* double was used here to prevent overflow. 0.1 is for round errs */ if ( *nint <= 0 ){ *nint = nintmax; } else if (*nint > nintmax) { rb_raise(rb_eArgError, "*nint is too long"); } if ( nbit > 32 ){ rb_raise(rb_eArgError, "nbit must be 32 or less"); } result = (int32_t *) malloc((*nint)*sizeof(int32_t)); for(i=0; i<(*nint); i++){ w = (i % 8) * nbit; n0 = (i / 8) * nbit + (w / 8); /* overflow-free i*nbit/8 */ k0 = w % 8; /* == (i*nbit) % 8 */ w = k0 + nbit - 1; n1 = n0 + (w/8); k1 = w % 8; mk0 = 0xff >> k0; /* to mask 0..k0-1 bits */ for(j=n1; j>= n1-3; j--){ j2 = j - n1 + 3; /* 3,2,1,0 */ mb = (nm = (8-nbit+(3-j2)*8)) > 0 ? (0xff>>nm): 0xff; if (j > n0) { cn[j2] = ptr[j] >> (7-k1); if (j != n0+1){ cn[j2] += ptr[j-1] << (k1+1); } else { cn[j2] += (ptr[j-1] & mk0) << (k1+1); } cn[j2] &= mb; } else if (j == n0) { cn[j2] = (ptr[j] & mk0) >> (7-k1); cn[j2] &= mb; } else { /* j < n0 --> blank */ cn[j2] = 0x00; } } result[i] = 0x1000000*cn[0] + 0x10000*cn[1] + 0x100*cn[2] + cn[3]; } return(result); } static VALUE mltbtnm_to_int32str(VALUE obj){ struct MultiBitNums *mbs; int32_t *buff; Data_Get_Struct(obj, struct MultiBitNums, mbs); buff = mltbtnm_read_int32(mbs->ptr, mbs->len_ptr, mbs->nbit, &(mbs->nint)); return rb_str_new( (char *) buff, mbs->nint * sizeof(int32_t) ); } void Init_multibitnums() { extern VALUE ruby_class; mNumRu = rb_define_module("NumRu"); cMultiBitNums = rb_define_class_under(mNumRu, "MultiBitNums", rb_cObject); rb_define_singleton_method(cMultiBitNums,"new",mltbtnm_s_new,-1); rb_define_method(cMultiBitNums, "to_int32str", mltbtnm_to_int32str,0); }