specialized_types.cc
Go to the documentation of this file.
00001 #include "typelib.hh"
00002 #include <iostream>
00003 
00004 #include <boost/bind.hpp>
00005 #include <typelib/value_ops.hh>
00006 
00007 using namespace Typelib;
00008 using std::vector;
00009 using namespace typelib_ruby;
00010 
00011 /**********************************************
00012  * Typelib::Compound
00013  */
00014 
00015 static VALUE compound_get_fields(VALUE self)
00016 {
00017     if (self == cCompound)
00018         return rb_ary_new();
00019 
00020     Type const& type(rb2cxx::object<Type>(self));
00021     Compound const& compound(dynamic_cast<Compound const&>(type));
00022     Compound::FieldList const& fields(compound.getFields());
00023     Compound::FieldList::const_iterator it, end = fields.end();
00024 
00025     VALUE registry  = type_get_registry(self);
00026     VALUE fieldlist = rb_ary_new();
00027     for (it = fields.begin(); it != end; ++it)
00028     {
00029         VALUE field_name = rb_str_new2(it->getName().c_str());
00030         VALUE field_type = cxx2rb::type_wrap(it->getType(), registry);
00031 
00032         VALUE field_def = rb_ary_new2(3);
00033         rb_ary_store(field_def, 0, field_name);
00034         rb_ary_store(field_def, 1, INT2FIX(it->getOffset()));
00035         rb_ary_store(field_def, 2, field_type);
00036         rb_ary_push(fieldlist, field_def);
00037     }
00038 
00039     return fieldlist;
00040 }
00041 
00042 /* Helper function for CompoundType#[] */
00043 static VALUE compound_field_get(VALUE rbvalue, VALUE name)
00044 { 
00045     VALUE registry = value_get_registry(rbvalue);
00046     Value value = rb2cxx::object<Value>(rbvalue);
00047     if (! value.getData())
00048         return Qnil;
00049 
00050     try { 
00051         Value field_value = value_get_field(value, StringValuePtr(name));
00052         return typelib_to_ruby(field_value, registry, rbvalue);
00053     } 
00054     catch(FieldNotFound)
00055     { rb_raise(rb_eArgError, "no field '%s'", StringValuePtr(name)); } 
00056     catch(std::exception const& e)
00057     { rb_raise(rb_eRuntimeError, "%s", e.what()); }
00058 }
00059 /* Helper function for CompoundType#[]= */
00060 static VALUE compound_field_set(VALUE self, VALUE name, VALUE newval)
00061 { 
00062     Value& tlib_value(rb2cxx::object<Value>(self));
00063 
00064     try {
00065         Value field_value = value_get_field(tlib_value, StringValuePtr(name));
00066         typelib_from_ruby(field_value, newval);
00067         return newval;
00068     }
00069     catch(FieldNotFound)
00070     { rb_raise(rb_eArgError, "no field '%s' in '%s'", StringValuePtr(name), rb_obj_classname(self)); }
00071     catch(std::exception const& e)
00072     { rb_raise(rb_eRuntimeError, "%s", e.what()); }
00073 }
00074 
00075 /* call-seq:
00076  *  pointer.deference => pointed-to type
00077  *
00078  * Returns the value pointed to by +self+ 
00079  */
00080 static VALUE pointer_deference(VALUE self)
00081 {
00082     VALUE pointed_to = rb_iv_get(self, "@points_to");
00083     if (!NIL_P(pointed_to))
00084         return pointed_to;
00085 
00086     Value const& value(rb2cxx::object<Value>(self));
00087     Indirect const& indirect(static_cast<Indirect const&>(value.getType()));
00088     
00089     VALUE registry = value_get_registry(self);
00090 
00091     void* ptr_value = *reinterpret_cast<void**>(value.getData());
00092     if (!ptr_value)
00093         rb_raise(rb_eArgError, "cannot deference a NULL pointer");
00094 
00095     Value new_value(ptr_value, indirect.getIndirection() );
00096     return typelib_to_ruby(new_value, registry, Qnil);
00097 }
00098 
00099 
00100 /* Get the C value associated with a ruby representation of an enum
00101  * Valid ruby representations are: symbols, strings and integer
00102  */
00103 Enum::integral_type rb2cxx::enum_value(VALUE rb_value, Enum const& e)
00104 {
00105     // m_value can be either an integer, a symbol or a string
00106     if (TYPE(rb_value) == T_FIXNUM)
00107     {
00108         Enum::integral_type value = FIX2INT(rb_value);
00109         try { 
00110             e.get(value); 
00111             return value;
00112         }
00113         catch(Enum::ValueNotFound) {  }
00114         rb_raise(rb_eArgError, "%i is not a valid value for %s", value, e.getName().c_str());
00115     }
00116 
00117     char const* name;
00118     if (SYMBOL_P(rb_value))
00119         name = rb_id2name(SYM2ID(rb_value));
00120     else
00121         name = StringValuePtr(rb_value);
00122 
00123     try { return e.get(name); }
00124     catch(Enum::SymbolNotFound) {  }
00125     rb_raise(rb_eArgError, "%s is not a valid symbol for %s", name, e.getName().c_str());
00126 }
00127 
00128 /* call-seq:
00129  *  enum.keys => array of keys
00130  *
00131  * Returns a string array of all the keys defined for this enumeration
00132  */
00133 VALUE enum_keys(VALUE self)
00134 {
00135     Enum const& type = static_cast<Enum const&>(rb2cxx::object<Type>(self));
00136 
00137     VALUE keys = rb_iv_get(self, "@values");
00138     if (!NIL_P(keys)) 
00139         return keys;
00140 
00141     keys = rb_hash_new();
00142     typedef std::list<std::string> string_list;
00143     string_list names = type.names();
00144     for (string_list::const_iterator it = names.begin(); it != names.end(); ++it)
00145         rb_hash_aset(keys, rb_str_new2(it->c_str()), INT2FIX(type.get(*it)));
00146 
00147     rb_iv_set(self, "@values", keys);
00148     return keys;
00149 }
00150 
00151 /* call-seq:
00152  *  enum.value_of(name) => integer
00153  *
00154  * Returns the integral value asoociated with the given name.
00155  */
00156 static VALUE enum_value_of(VALUE self, VALUE name)
00157 {
00158     Enum const& type = static_cast<Enum const&>(rb2cxx::object<Type>(self));
00159 
00160     try {
00161         int value = type.get(StringValuePtr(name));
00162         return INT2NUM(value);
00163     } catch (Enum::SymbolNotFound) {
00164         rb_raise(rb_eArgError, "this enumeration has no value for %s", StringValuePtr(name));
00165     }
00166 }
00167 
00168 /* call-seq:
00169  *  enum.name_of(integer) => key
00170  *
00171  * Returns the symbolic name of +integer+ in this enumeration, or raises
00172  * ArgumentError if there is no matching name.
00173  */
00174 static VALUE enum_name_of(VALUE self, VALUE integer)
00175 {
00176     Enum const& type = static_cast<Enum const&>(rb2cxx::object<Type>(self));
00177 
00178     try {
00179         std::string name = type.get(NUM2INT(integer));
00180         return rb_str_new2(name.c_str());
00181     } catch (Enum::ValueNotFound) {
00182         rb_raise(rb_eArgError, "this enumeration has no name for %i", NUM2INT(integer));
00183     }
00184 }
00185 
00186 /**********************************************
00187  * Typelib::Pointer
00188  */
00189 
00190 /* call-seq:
00191  *  type.deference => other_type
00192  *
00193  * Returns the type referenced by this one
00194  */
00195 static VALUE indirect_type_deference(VALUE self)
00196 {
00197     VALUE registry = type_get_registry(self);
00198     Type const& type(rb2cxx::object<Type>(self));
00199     Indirect const& indirect(static_cast<Indirect const&>(type));
00200     return cxx2rb::type_wrap(indirect.getIndirection(), registry);
00201 }
00202 
00203 
00204 static Value array_element(VALUE rbarray, VALUE rbindex)
00205 {
00206     Value& value(rb2cxx::object<Value>(rbarray));
00207     Array const& array(static_cast<Array const&>(value.getType()));
00208     size_t index = NUM2INT(rbindex);
00209     
00210     if (index >= array.getDimension())
00211     {
00212         rb_raise(rb_eIndexError, "Out of bounds: %lu > %lu", index, array.getDimension());
00213         return Value();
00214     }
00215 
00216     Type const& array_type(array.getIndirection());
00217 
00218     int8_t* data = reinterpret_cast<int8_t*>(value.getData());
00219     data += array_type.getSize() * index;
00220     return Value(data, array_type);
00221 }
00222 
00223 /* call-seq:
00224  *  array[index]    => value
00225  *
00226  * Returns the value at +index+ in the array. Since Typelib arrays are *not*
00227  * dynamically extensible, trying to set a non-existent index will raise an
00228  * IndexError exception.
00229  */
00230 static VALUE array_get(int argc, VALUE* argv, VALUE self)
00231 { 
00232     Value& value            = rb2cxx::object<Value>(self);
00233     Array const& array      = static_cast<Array const&>(value.getType());
00234     if (array.getDimension() == 0)
00235         return self;
00236 
00237     Type  const& array_type = array.getIndirection();
00238     VALUE registry          = value_get_registry(self);
00239 
00240     int8_t* data = reinterpret_cast<int8_t*>(value.getData());
00241     size_t index = NUM2INT(argv[0]);
00242     if (index >= array.getDimension())
00243         rb_raise(rb_eIndexError, "Out of bounds: %li > %li", index, array.getDimension());
00244 
00245     if (argc == 1)
00246     {
00247         Value v = Value(data + array_type.getSize() * index, array_type);
00248         return typelib_to_ruby( v, registry, self );
00249     }
00250     else if (argc == 2)
00251     {
00252         VALUE ret = rb_ary_new();
00253         size_t size = NUM2INT(argv[1]);
00254         if (index + size > array.getDimension())
00255             rb_raise(rb_eIndexError, "Out of bounds: %li > %li", index + size - 1, array.getDimension());
00256 
00257         for (size_t i = index; i < index + size; ++i)
00258         {
00259             Value v = Value(data + array_type.getSize() * i, array_type);
00260             VALUE rb_v = typelib_to_ruby( v, registry, self );
00261 
00262             rb_ary_push(ret, rb_v);
00263         }
00264 
00265         return ret;
00266     }
00267     else
00268         rb_raise(rb_eArgError, "invalid argument count (%i for 1 or 2)", argc);
00269 }
00270 
00271 /* call-seq:
00272  *  array[index] = new_value    => new_value
00273  *
00274  * Sets the value at +index+ to +new_value+. Since Typelib arrays are *not*
00275  * dynamically extensible, trying to set a non-existent index will raise an
00276  * IndexError exception.
00277  */
00278 static VALUE array_set(VALUE self, VALUE rbindex, VALUE newvalue)
00279 { 
00280     Value element = array_element(self, rbindex);
00281     return typelib_from_ruby(element, newvalue); 
00282 }
00283 
00284 /* call-seq:
00285  *  array.each { |v| ... }      => array
00286  *
00287  * Iterates on all elements of the array
00288  */
00289 static VALUE array_do_each(VALUE rbarray)
00290 {
00291     Value& value            = rb2cxx::object<Value>(rbarray);
00292     Array const& array      = static_cast<Array const&>(value.getType());
00293     if (array.getDimension() == 0)
00294         return rbarray;
00295 
00296     Type  const& array_type = array.getIndirection();
00297     VALUE registry          = value_get_registry(rbarray);
00298 
00299     int8_t* data = reinterpret_cast<int8_t*>(value.getData());
00300 
00301     for (size_t i = 0; i < array.getDimension(); ++i, data += array_type.getSize())
00302         rb_yield(typelib_to_ruby( Value(data, array_type), registry, rbarray ));
00303 
00304     return rbarray;
00305 }
00306 
00307 /* call-seq:
00308  *  array.size              => size
00309  *
00310  * Returns the count of elements in +array+
00311  */
00312 static VALUE array_size(VALUE rbarray)
00313 {
00314     Value& value(rb2cxx::object<Value>(rbarray));
00315     Array const& array(static_cast<Array const&>(value.getType()));
00316     return INT2FIX(array.getDimension());
00317 }
00318 
00319 /* call-seq:
00320  *  array.length                    => length
00321  *
00322  * Returns the count of elemnts in +array+
00323  */
00324 static VALUE array_class_length(VALUE rbarray)
00325 {
00326     Array const& array(dynamic_cast<Array const&>(rb2cxx::object<Type>(rbarray)));
00327     return INT2FIX(array.getDimension());
00328 }
00329 
00330 /*
00331  * call-seq:
00332  *  pointer.null?               => boolean
00333  *
00334  * checks if this is a NULL pointer 
00335  */
00336 static VALUE pointer_nil_p(VALUE self)
00337 {
00338     Value const& value(rb2cxx::object<Value>(self));
00339     if ( *reinterpret_cast<void**>(value.getData()) == 0 )
00340         return Qtrue;
00341     return Qfalse;
00342 }
00343 
00344 /*
00345  * call-seq:
00346  *  numeric.integer?        => true or false
00347  *
00348  * Returns true if the type is an integral type and false if it is a floating-point type
00349  */
00350 static VALUE numeric_type_integer_p(VALUE self)
00351 {
00352     Numeric const& type(dynamic_cast<Numeric const&>(rb2cxx::object<Type>(self)));
00353     return type.getNumericCategory() == Numeric::Float ? Qfalse : Qtrue;
00354 }
00355 
00356 /*
00357  * call-seq:
00358  *  numeric.size            => value
00359  *
00360  * The size of this type in bytes
00361  */
00362 static VALUE numeric_type_size(VALUE self)
00363 {
00364     Numeric const& type(dynamic_cast<Numeric const&>(rb2cxx::object<Type>(self)));
00365     return INT2FIX(type.getSize());
00366 }
00367 
00368 /*
00369  * call-seq:
00370  *  numeric.unsigned?       => value
00371  *
00372  * If integer? returns true, returns whether this type is an unsigned or signed
00373  * integral type.
00374  */
00375 static VALUE numeric_type_unsigned_p(VALUE self)
00376 {
00377     Numeric const& type(dynamic_cast<Numeric const&>(rb2cxx::object<Type>(self)));
00378     switch(type.getNumericCategory())
00379     {
00380         case Numeric::SInt: return Qfalse;
00381         case Numeric::UInt: return Qtrue;
00382         case Numeric::Float:
00383             rb_raise(rb_eArgError, "not an integral type");
00384     }
00385     return Qnil; // never reached
00386 }
00387 
00388 
00389 /*
00390  * call-seq:
00391  *  klass.container_kind => name
00392  *
00393  * Returns the name of the generic container. For instance, a
00394  * /std/vector</double> type would return /std/vector.
00395  */
00396 static VALUE container_kind(VALUE self)
00397 {
00398     Container const& type(dynamic_cast<Container const&>(rb2cxx::object<Type>(self)));
00399     return rb_str_new2(type.kind().c_str());
00400 }
00401 
00402 /*
00403  * call-seq:
00404  *  container.natural_size => a_number
00405  *
00406  * Returns the container's size on the local machine. This can be different from
00407  * the value returned by size() in case a registry has been generated on a
00408  * different architecture.
00409  */
00410 static VALUE container_natural_size(VALUE self)
00411 {
00412     Container const& type(dynamic_cast<Container const&>(rb2cxx::object<Type>(self)));
00413     return INT2FIX(type.getNaturalSize());
00414 }
00415 
00416 /*
00417  * call-seq:
00418  *  container.random_access?
00419  *
00420  * Returns true if this container type is a random access container
00421  */
00422 static VALUE container_random_access_p(VALUE self)
00423 {
00424     Container const& type(dynamic_cast<Container const&>(rb2cxx::object<Type>(self)));
00425     return type.isRandomAccess() ? Qtrue : Qfalse;
00426 }
00427 
00428 
00429 /*
00430  * call-seq:
00431  *  container.length => value
00432  *
00433  * Returns the count of elements in +container+
00434  */
00435 static VALUE container_length(VALUE self)
00436 {
00437     Value value = rb2cxx::object<Value>(self);
00438     Container const& type(dynamic_cast<Container const&>(value.getType()));
00439 
00440     return INT2NUM(type.getElementCount(value.getData()));
00441 }
00442 
00443 /*
00444  * call-seq:
00445  *  container.clear
00446  *
00447  * Removes all elements from that container
00448  */
00449 static VALUE container_clear(VALUE self)
00450 {
00451     Value value = rb2cxx::object<Value>(self);
00452     Container const& type(dynamic_cast<Container const&>(value.getType()));
00453 
00454     type.clear(value.getData());
00455     return Qnil;
00456 }
00457 
00458 static Typelib::Value container_element(uint64_t* buffer10, Type const& element_t, VALUE obj)
00459 {
00460     Typelib::Value element_v;
00461     if (element_t.getCategory() == Type::Numeric && sizeof(int64_t) * 10 >= element_t.getSize())
00462     {
00463         // Special case: allow the caller to use Ruby numeric directly. This is
00464         // way faster if a lot of insertions need to be done
00465         element_v = Value(buffer10, element_t);
00466         typelib_from_ruby(element_v, obj);
00467     }
00468     else
00469     {
00470         element_v   = rb2cxx::object<Value>(obj);
00471         if (element_t != element_v.getType())
00472             rb_raise(rb_eArgError, "wrong type %s for new element, expected %s", element_v.getType().getName().c_str(), element_t.getName().c_str());
00473     }
00474     return element_v;
00475 }
00476 
00477 static VALUE container_do_push(VALUE self, VALUE obj)
00478 {
00479     Value container_v = rb2cxx::object<Value>(self);
00480     Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00481 
00482     uint64_t buffer[10];
00483     Value element_v = container_element(buffer, container_t.getIndirection(), obj);
00484     container_t.push(container_v.getData(), element_v);
00485     return self;
00486 }
00487 
00488 static VALUE container_do_set(VALUE self, VALUE index, VALUE obj)
00489 {
00490     Value container_v = rb2cxx::object<Value>(self);
00491     Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00492 
00493     uint64_t buffer[10];
00494     Value element_v = container_element(buffer, container_t.getIndirection(), obj);
00495     container_t.setElement(container_v.getData(), NUM2INT(index), element_v);
00496     return self;
00497 }
00498 
00499 static VALUE container_do_get(VALUE self, VALUE index)
00500 {
00501     Value container_v = rb2cxx::object<Value>(self);
00502     Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00503     VALUE registry = value_get_registry(self);
00504 
00505     Value v = container_t.getElement(container_v.getData(), NUM2INT(index));
00506     return typelib_to_ruby(v, registry, self);
00507 }
00508 
00509 struct ContainerIterator : public RubyGetter
00510 {
00511     bool inside;
00512 
00513     bool visit_(Value const& v, Container const& c)
00514     { 
00515         if (inside)
00516             RubyGetter::visit_(v, c);
00517         else
00518             ValueVisitor::visit_(v, c);
00519         return false;
00520     }
00521 
00522     void apply(Value v, VALUE registry, VALUE parent)
00523     {
00524         inside = false;
00525         RubyGetter::apply(v, registry, parent);
00526     }
00527     virtual void dispatch(Value v)
00528     {
00529         inside = true;
00530         RubyGetter::dispatch(v);
00531 
00532         VALUE result = m_value;
00533         m_value = Qnil;
00534         rb_yield(result);
00535     }
00536 };
00537 
00538 /*
00539  * call-seq:
00540  *  container.each { |obj| ... } => container
00541  *
00542  * Iterates on the elements of the container
00543  */
00544 static VALUE container_each(VALUE self)
00545 {
00546     Value value = rb2cxx::object<Value>(self);
00547     VALUE registry = value_get_registry(self);
00548     ContainerIterator iterator;
00549     iterator.apply(value, registry, self);
00550     return self;
00551 }
00552 
00553 /*
00554  * call-seq:
00555  *  container.erase(obj) => true or false
00556  *
00557  * Removes +obj+ from the container. Returns true if +obj+ has been found and
00558  * deleted, and false otherwise
00559  */
00560 static VALUE container_erase(VALUE self, VALUE obj)
00561 {
00562     Value container_v = rb2cxx::object<Value>(self);
00563     Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00564 
00565     uint64_t buffer[10];
00566     Value element_v = container_element(buffer, container_t.getIndirection(), obj);
00567 
00568     if (container_t.erase(container_v.getData(), element_v))
00569         return Qtrue;
00570     else
00571         return Qfalse;
00572 }
00573 
00574 bool container_delete_if_i(Value v, VALUE registry, VALUE container)
00575 {
00576     VALUE rb_v = typelib_to_ruby(v, registry, container);
00577     if (RTEST(rb_yield(rb_v)))
00578         return true;
00579     return false;
00580 }
00581 
00582 /*
00583  * call-seq:
00584  *  container.delete_if { |obj| ... } => container
00585  *
00586  * Removes the elements in the container for which the block returns true.
00587  */
00588 static VALUE container_delete_if(VALUE self)
00589 {
00590     Value container_v = rb2cxx::object<Value>(self);
00591     Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00592 
00593     VALUE registry = value_get_registry(self);
00594     container_t.delete_if(container_v.getData(), boost::bind(container_delete_if_i, _1, registry, self));
00595     return self;
00596 }
00597 
00598 /* 
00599  * call-seq:
00600  *   value.to_ruby      => non-Typelib object or self
00601  *
00602  * Converts +self+ to its Ruby equivalent. If no equivalent
00603  * type is available, returns self
00604  */
00605 static VALUE numeric_to_ruby(VALUE self)
00606 {
00607     Value const& value(rb2cxx::object<Value>(self));
00608     VALUE registry = value_get_registry(self);
00609     try {
00610         return typelib_to_ruby(value, registry, Qnil);
00611     } catch(Typelib::NullTypeFound) { }
00612     rb_raise(rb_eTypeError, "trying to convert 'void'");
00613 }
00614 
00615 /*
00616  * call-seq:
00617  *   value.from_ruby(ruby_object) => self
00618  *
00619  * Initializes +self+ with the information contained in +ruby_object+.
00620  *
00621  * This particular method is not type-safe. You should use Typelib.from_ruby
00622  * unless you know what you are doing.
00623  */
00624 static VALUE numeric_from_ruby(VALUE self, VALUE arg)
00625 {
00626     Value& value(rb2cxx::object<Value>(self));
00627     try {
00628         typelib_from_ruby(value, arg);
00629         return self;
00630     } catch(Typelib::UnsupportedType) { }
00631     rb_raise(rb_eTypeError, "cannot perform the requested convertion");
00632 }
00633 
00634 
00635 /* Document-class: Typelib::NumericType
00636  *
00637  * Wrapper for numeric types (int, float, ...)
00638  */
00639 
00640 /* Document-class: Typelib::IndirectType
00641  *
00642  * Base class for types which deference other objects, like pointers or arrays
00643  * See also ArrayType and PointerType
00644  */
00645 
00646 /* Document-class: Typelib::PointerType
00647  *
00648  * Base class for pointers (references to other values)
00649  */
00650 
00651 /* Document-class: Typelib::CompoundType
00652  *
00653  * Base class for types composed by other types (structures and unions in C).
00654  * Each field is assigned its type and its offset inside the structure. So
00655  * unions are represented with all fields having an offset of zero, while
00656  * structures have consecutive offsets.
00657  */
00658 
00659 void typelib_ruby::Typelib_init_specialized_types()
00660 {
00661     VALUE mTypelib  = rb_define_module("Typelib");
00662     cNumeric   = rb_define_class_under(mTypelib, "NumericType", cType);
00663     rb_define_singleton_method(cNumeric, "integer?", RUBY_METHOD_FUNC(numeric_type_integer_p), 0);
00664     rb_define_singleton_method(cNumeric, "unsigned?", RUBY_METHOD_FUNC(numeric_type_unsigned_p), 0);
00665     rb_define_singleton_method(cNumeric, "size", RUBY_METHOD_FUNC(numeric_type_size), 0);
00666     rb_define_method(cNumeric, "typelib_to_ruby",      RUBY_METHOD_FUNC(&numeric_to_ruby), 0);
00667     rb_define_method(cNumeric, "typelib_from_ruby", RUBY_METHOD_FUNC(&numeric_from_ruby), 1);
00668 
00669     cOpaque    = rb_define_class_under(mTypelib, "OpaqueType", cType);
00670     cNull      = rb_define_class_under(mTypelib, "NullType", cType);
00671 
00672     cIndirect  = rb_define_class_under(mTypelib, "IndirectType", cType);
00673     rb_define_singleton_method(cIndirect, "deference",    RUBY_METHOD_FUNC(indirect_type_deference), 0);
00674 
00675     cPointer  = rb_define_class_under(mTypelib, "PointerType", cIndirect);
00676     rb_define_method(cPointer, "deference", RUBY_METHOD_FUNC(pointer_deference), 0);
00677     rb_define_method(cPointer, "null?", RUBY_METHOD_FUNC(pointer_nil_p), 0);
00678     
00679     cCompound = rb_define_class_under(mTypelib, "CompoundType", cType);
00680     rb_define_singleton_method(cCompound, "get_fields",   RUBY_METHOD_FUNC(compound_get_fields), 0);
00681     rb_define_method(cCompound, "typelib_get_field", RUBY_METHOD_FUNC(compound_field_get), 1);
00682     rb_define_method(cCompound, "typelib_set_field", RUBY_METHOD_FUNC(compound_field_set), 2);
00683 
00684     cEnum = rb_define_class_under(mTypelib, "EnumType", cType);
00685     rb_define_singleton_method(cEnum, "keys", RUBY_METHOD_FUNC(enum_keys), 0);
00686     rb_define_singleton_method(cEnum, "value_of",      RUBY_METHOD_FUNC(enum_value_of), 1);
00687     rb_define_singleton_method(cEnum, "name_of",      RUBY_METHOD_FUNC(enum_name_of), 1);
00688     rb_define_method(cEnum, "typelib_to_ruby",      RUBY_METHOD_FUNC(&numeric_to_ruby), 0);
00689     rb_define_method(cEnum, "typelib_from_ruby",    RUBY_METHOD_FUNC(&numeric_from_ruby), 1);
00690 
00691     cArray    = rb_define_class_under(mTypelib, "ArrayType", cIndirect);
00692     rb_define_singleton_method(cArray, "length", RUBY_METHOD_FUNC(array_class_length), 0);
00693     rb_define_method(cArray, "do_get",  RUBY_METHOD_FUNC(array_get), -1);
00694     rb_define_method(cArray, "do_set",  RUBY_METHOD_FUNC(array_set), 2);
00695     rb_define_method(cArray, "do_each",    RUBY_METHOD_FUNC(array_do_each), 0);
00696     rb_define_method(cArray, "size",    RUBY_METHOD_FUNC(array_size), 0);
00697 
00698     cContainer = rb_define_class_under(mTypelib, "ContainerType", cIndirect);
00699     rb_define_singleton_method(cContainer, "container_kind", RUBY_METHOD_FUNC(container_kind), 0);
00700     rb_define_singleton_method(cContainer, "natural_size",   RUBY_METHOD_FUNC(container_natural_size), 0);
00701     rb_define_singleton_method(cContainer, "random_access?",   RUBY_METHOD_FUNC(container_random_access_p), 0);
00702     rb_define_method(cContainer, "length",    RUBY_METHOD_FUNC(container_length), 0);
00703     rb_define_method(cContainer, "size",    RUBY_METHOD_FUNC(container_length), 0);
00704     rb_define_method(cContainer, "do_clear",    RUBY_METHOD_FUNC(container_clear), 0);
00705     rb_define_method(cContainer, "do_push",    RUBY_METHOD_FUNC(container_do_push), 1);
00706     rb_define_method(cContainer, "do_get",    RUBY_METHOD_FUNC(container_do_get), 1);
00707     rb_define_method(cContainer, "do_set",    RUBY_METHOD_FUNC(container_do_set), 2);
00708     rb_define_method(cContainer, "do_each",      RUBY_METHOD_FUNC(container_each), 0);
00709     rb_define_method(cContainer, "do_erase",     RUBY_METHOD_FUNC(container_erase), 1);
00710     rb_define_method(cContainer, "do_delete_if", RUBY_METHOD_FUNC(container_delete_if), 0);
00711 }
00712 


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Thu Jan 2 2014 11:38:41