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