Go to the documentation of this file.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
00073
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