$search
00001 #ifndef __RUBY_EXT_TYPELIB_HH__ 00002 #define __RUBY_EXT_TYPELIB_HH__ 00003 00004 #include <ruby.h> 00005 #include <typelib/typemodel.hh> 00006 #include <typelib/value.hh> 00007 #include <typelib/registry.hh> 00008 00009 #include "typelib_ruby.hh" 00010 00011 #undef VERBOSE 00012 00013 namespace typelib_ruby { 00014 extern VALUE cType; 00015 extern VALUE cIndirect; 00016 extern VALUE cPointer; 00017 extern VALUE cArray; 00018 extern VALUE cCompound; 00019 extern VALUE cNumeric; 00020 extern VALUE cEnum; 00021 extern VALUE cContainer; 00022 extern VALUE cOpaque; 00023 extern VALUE cNull; 00024 extern VALUE cRegistry; 00025 00026 extern VALUE eNotFound; 00027 00029 extern void Typelib_init_memory(); 00030 extern void Typelib_init_values(); 00031 extern void Typelib_init_strings(); 00032 extern void Typelib_init_specialized_types(); 00033 extern void Typelib_init_registry(); 00034 #ifdef WITH_DYNCALL 00035 extern void Typelib_init_functions(); 00036 #endif 00037 00038 namespace cxx2rb { 00039 using namespace Typelib; 00040 00041 typedef std::map<Type const*, std::pair<bool, VALUE> > WrapperMap; 00042 00043 struct RbRegistry 00044 { 00045 boost::shared_ptr<Typelib::Registry> registry; 00056 cxx2rb::WrapperMap wrappers; 00057 00058 RbRegistry(Typelib::Registry* registry) 00059 : registry(registry) {} 00060 ~RbRegistry() {} 00061 }; 00062 00063 VALUE class_of(Type const& type); 00064 00065 template<typename T> VALUE class_of(); 00066 template<> inline VALUE class_of<Value>() { return cType; } 00067 template<> inline VALUE class_of<Type>() { return rb_cClass; } 00068 template<> inline VALUE class_of<RbRegistry>() { return cRegistry; } 00069 00070 VALUE type_wrap(Type const& type, VALUE registry); 00071 00072 /* Get the Ruby symbol associated with a C enum, or nil 00073 * if the value is not valid for this enum 00074 */ 00075 inline VALUE enum_symbol(Enum::integral_type value, Enum const& e) 00076 { 00077 try { 00078 std::string symbol = e.get(value); 00079 return ID2SYM(rb_intern(symbol.c_str())); 00080 } 00081 catch(Enum::ValueNotFound) { return Qnil; } 00082 } 00083 00084 VALUE value_wrap(Value v, VALUE registry, VALUE parent = Qnil); 00085 } 00086 00087 namespace rb2cxx { 00088 using namespace Typelib; 00089 00090 inline void check_is_kind_of(VALUE self, VALUE expected) 00091 { 00092 if (! rb_obj_is_kind_of(self, expected)) 00093 rb_raise(rb_eTypeError, "expected %s, got %s", rb_class2name(expected), rb_obj_classname(self)); 00094 } 00095 00096 template<typename T> 00097 T& get_wrapped(VALUE self) 00098 { 00099 void* object = 0; 00100 Data_Get_Struct(self, void, object); 00101 return *reinterpret_cast<T*>(object); 00102 } 00103 00104 template<typename T> 00105 T& object(VALUE self) 00106 { 00107 check_is_kind_of(self, cxx2rb::class_of<T>()); 00108 return get_wrapped<T>(self); 00109 } 00110 00111 template<> inline Registry& object(VALUE self) 00112 { 00113 return *object<cxx2rb::RbRegistry>(self).registry; 00114 } 00115 00116 template<> 00117 inline Type& object(VALUE self) 00118 { 00119 check_is_kind_of(self, rb_cClass); 00120 VALUE type = rb_iv_get(self, "@type"); 00121 return get_wrapped<Type>(type); 00122 } 00123 00124 Enum::integral_type enum_value(VALUE rb_value, Enum const& e); 00125 } 00126 00127 class RubyGetter : public Typelib::ValueVisitor 00128 { 00129 protected: 00130 VALUE m_value; 00131 VALUE m_registry; 00132 VALUE m_parent; 00133 00134 bool visit_ (int8_t & value); 00135 bool visit_ (uint8_t & value); 00136 bool visit_ (int16_t & value); 00137 bool visit_ (uint16_t& value); 00138 bool visit_ (int32_t & value); 00139 bool visit_ (uint32_t& value); 00140 bool visit_ (int64_t & value); 00141 bool visit_ (uint64_t& value); 00142 bool visit_ (float & value); 00143 bool visit_ (double & value); 00144 00145 bool visit_(Typelib::Value const& v, Typelib::Pointer const& p); 00146 bool visit_(Typelib::Value const& v, Typelib::Array const& a); 00147 bool visit_(Typelib::Value const& v, Typelib::Compound const& c); 00148 bool visit_(Typelib::Value const& v, Typelib::Container const& c); 00149 bool visit_(Typelib::Value const& v, Typelib::OpaqueType const& c); 00150 bool visit_(Typelib::Enum::integral_type& v, Typelib::Enum const& e); 00151 00152 public: 00153 RubyGetter(); 00154 ~RubyGetter(); 00155 00156 VALUE apply(Typelib::Value value, VALUE registry, VALUE parent); 00157 }; 00158 00159 class RubySetter : public Typelib::ValueVisitor 00160 { 00161 protected: 00162 VALUE m_value; 00163 00164 bool visit_ (int8_t & value); 00165 bool visit_ (uint8_t & value); 00166 bool visit_ (int16_t & value); 00167 bool visit_ (uint16_t& value); 00168 bool visit_ (int32_t & value); 00169 bool visit_ (uint32_t& value); 00170 bool visit_ (int64_t & value); 00171 bool visit_ (uint64_t& value); 00172 bool visit_ (float & value); 00173 bool visit_ (double & value); 00174 00175 bool visit_(Typelib::Value const& v, Typelib::Pointer const& p); 00176 bool visit_(Typelib::Value const& v, Typelib::Array const& a); 00177 bool visit_(Typelib::Value const& v, Typelib::Compound const& c); 00178 bool visit_(Typelib::Value const& v, Typelib::Container const& c); 00179 bool visit_(Typelib::Value const& v, Typelib::OpaqueType const& c); 00180 bool visit_(Typelib::Enum::integral_type& v, Typelib::Enum const& e); 00181 00182 public: 00183 RubySetter(); 00184 ~RubySetter(); 00185 00186 VALUE apply(Typelib::Value value, VALUE new_value); 00187 }; 00188 00189 extern VALUE value_get_registry(VALUE self); 00190 extern VALUE type_get_registry(VALUE self); 00191 extern void memory_unref(void* ptr); 00192 extern void memory_delete(void* ptr); 00193 extern VALUE memory_wrap(void* ptr, bool take_ownership, void* root_ptr); 00194 extern VALUE memory_allocate(size_t size); 00195 extern void memory_init(VALUE ptr, VALUE type); 00196 extern void* memory_cptr(VALUE ptr); 00197 } 00198 00199 #endif 00200