2012-05-09 14:12:44 -04:00
|
|
|
#include "rr.h"
|
|
|
|
|
|
|
|
namespace rr {
|
|
|
|
|
2012-05-21 17:36:19 -04:00
|
|
|
VALUE Accessor::Info::Class;
|
2012-05-09 14:12:44 -04:00
|
|
|
|
|
|
|
void Accessor::Init() {
|
|
|
|
ClassBuilder("AccessorInfo").
|
2012-05-21 17:36:19 -04:00
|
|
|
defineMethod("This", &Info::This).
|
|
|
|
defineMethod("Holder", &Info::Holder).
|
|
|
|
defineMethod("Data", &Info::Data).
|
|
|
|
store(&Info::Class);
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
|
|
|
|
2012-05-22 13:12:08 -04:00
|
|
|
Accessor::Accessor(VALUE getter, VALUE setter, VALUE data_) : get(getter), set(setter), data(data_) {}
|
|
|
|
|
|
|
|
Accessor::Accessor(VALUE get, VALUE set, VALUE query, VALUE deleter, VALUE enumerator, VALUE data) {
|
2012-05-21 17:36:19 -04:00
|
|
|
this->get = get;
|
|
|
|
this->set = set;
|
2012-05-22 13:12:08 -04:00
|
|
|
this->query = query;
|
|
|
|
this->deleter = deleter;
|
|
|
|
this->enumerator = enumerator;
|
2012-05-21 17:36:19 -04:00
|
|
|
this->data = data;
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
|
|
|
|
2012-05-21 17:36:19 -04:00
|
|
|
Accessor::Accessor(v8::Handle<v8::Value> value) {
|
|
|
|
v8::Local<v8::Object> wrapper = value->ToObject();
|
|
|
|
this->get = unwrap(wrapper, 0);
|
|
|
|
this->set = unwrap(wrapper, 1);
|
2012-05-22 22:55:31 -04:00
|
|
|
this->query = unwrap(wrapper, 2);
|
|
|
|
this->deleter = unwrap(wrapper, 3);
|
|
|
|
this->enumerator = unwrap(wrapper, 4);
|
|
|
|
v8::Handle<v8::Value> data = wrapper->Get(5);
|
2012-05-21 17:36:19 -04:00
|
|
|
if (!data.IsEmpty()) {
|
|
|
|
this->data = Value(data);
|
|
|
|
}
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
|
|
|
|
2012-05-21 17:36:19 -04:00
|
|
|
Accessor::operator v8::Handle<v8::Value>() {
|
|
|
|
v8::Local<v8::Object> wrapper = v8::Object::New();
|
|
|
|
wrap(wrapper, 0, this->get);
|
|
|
|
wrap(wrapper, 1, this->set);
|
2012-05-22 22:55:31 -04:00
|
|
|
wrap(wrapper, 2, this->query);
|
|
|
|
wrap(wrapper, 3, this->deleter);
|
|
|
|
wrap(wrapper, 4, this->enumerator);
|
2012-05-21 17:36:19 -04:00
|
|
|
if (RTEST(this->data)) {
|
2012-05-22 22:55:31 -04:00
|
|
|
wrapper->Set(5, Value(this->data));
|
2012-05-21 17:36:19 -04:00
|
|
|
}
|
|
|
|
return wrapper;
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
2012-05-21 17:36:19 -04:00
|
|
|
|
|
|
|
void Accessor::wrap(v8::Handle<v8::Object> wrapper, int index, VALUE value) {
|
2012-05-22 22:55:31 -04:00
|
|
|
if (RTEST(value)) {
|
|
|
|
wrapper->Set(index, External::wrap(value));
|
|
|
|
}
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
|
|
|
|
2012-05-21 17:36:19 -04:00
|
|
|
VALUE Accessor::unwrap(v8::Handle<v8::Object> wrapper, int index) {
|
2012-05-22 22:55:31 -04:00
|
|
|
v8::Handle<v8::Value> value = wrapper->Get(index);
|
|
|
|
if (value.IsEmpty()) {
|
|
|
|
return Qnil;
|
|
|
|
} else {
|
|
|
|
v8::Handle<v8::External> external(v8::External::Cast(*value));
|
|
|
|
return External::unwrap(external);
|
|
|
|
}
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
|
|
|
|
2012-05-22 13:12:08 -04:00
|
|
|
|
2012-05-21 17:36:19 -04:00
|
|
|
VALUE Accessor::Info::This(VALUE self) {
|
|
|
|
return Object(Info(self)->This());
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
|
|
|
|
2012-05-21 17:36:19 -04:00
|
|
|
VALUE Accessor::Info::Holder(VALUE self) {
|
|
|
|
return Object(Info(self)->Holder());
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
2012-05-21 17:36:19 -04:00
|
|
|
|
|
|
|
VALUE Accessor::Info::Data(VALUE self) {
|
|
|
|
return Accessor(Info(self)->Data()).data;
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
2012-05-21 17:36:19 -04:00
|
|
|
|
2012-05-22 13:12:08 -04:00
|
|
|
v8::Handle<v8::Value> Accessor::AccessorGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
2012-05-21 17:36:19 -04:00
|
|
|
return Info(info).get(property);
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
2012-05-21 17:36:19 -04:00
|
|
|
|
2012-05-22 13:12:08 -04:00
|
|
|
void Accessor::AccessorSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
|
2012-05-21 17:36:19 -04:00
|
|
|
Info(info).set(property, value);
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
2012-05-22 13:12:08 -04:00
|
|
|
v8::Handle<v8::Value> Accessor::NamedPropertyGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
|
|
|
return Info(info).get(property);
|
|
|
|
}
|
|
|
|
v8::Handle<v8::Value> Accessor::NamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
|
|
|
|
return Info(info).set(property, value);
|
|
|
|
}
|
|
|
|
v8::Handle<v8::Integer> Accessor::NamedPropertyQuery(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
|
|
|
return Info(info).query(property);
|
|
|
|
}
|
|
|
|
v8::Handle<v8::Boolean> Accessor::NamedPropertyDeleter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
|
|
|
return Info(info).remove(property);
|
|
|
|
}
|
|
|
|
v8::Handle<v8::Array> Accessor::NamedPropertyEnumerator(const v8::AccessorInfo& info) {
|
|
|
|
return Info(info).enumerateNames();
|
|
|
|
}
|
|
|
|
|
|
|
|
v8::Handle<v8::Value> Accessor::IndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) {
|
|
|
|
return Info(info).get(index);
|
|
|
|
}
|
|
|
|
v8::Handle<v8::Value> Accessor::IndexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
|
|
|
|
return Info(info).set(index, value);
|
|
|
|
}
|
|
|
|
v8::Handle<v8::Integer> Accessor::IndexedPropertyQuery(uint32_t index, const v8::AccessorInfo& info) {
|
|
|
|
return Info(info).query(index);
|
|
|
|
}
|
|
|
|
v8::Handle<v8::Boolean> Accessor::IndexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info) {
|
|
|
|
return Info(info).remove(index);
|
|
|
|
}
|
|
|
|
v8::Handle<v8::Array> Accessor::IndexedPropertyEnumerator(const v8::AccessorInfo& info) {
|
|
|
|
return Info(info).enumerateIndices();
|
|
|
|
}
|
2012-05-21 17:36:19 -04:00
|
|
|
|
|
|
|
Accessor::Info::Info(const v8::AccessorInfo& info) {
|
|
|
|
this->info = &info;
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
2012-05-21 17:36:19 -04:00
|
|
|
|
|
|
|
Accessor::Info::Info(VALUE value) {
|
|
|
|
Data_Get_Struct(value, class v8::AccessorInfo, info);
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
2012-05-21 17:36:19 -04:00
|
|
|
|
|
|
|
v8::Handle<v8::Value> Accessor::Info::get(v8::Local<v8::String> property) {
|
|
|
|
Accessor accessor(info->Data());
|
|
|
|
return Value(rb_funcall(accessor.get, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this));
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
|
|
|
|
2012-05-22 13:12:08 -04:00
|
|
|
v8::Handle<v8::Value> Accessor::Info::set(v8::Local<v8::String> property, v8::Local<v8::Value> value) {
|
2012-05-21 17:36:19 -04:00
|
|
|
Accessor accessor(info->Data());
|
2012-05-22 13:12:08 -04:00
|
|
|
return Value(rb_funcall(accessor.set, rb_intern("call"), 3, (VALUE)String(property), (VALUE)Value(value), (VALUE)*this));
|
2012-05-21 17:36:19 -04:00
|
|
|
}
|
2012-05-22 13:12:08 -04:00
|
|
|
|
|
|
|
v8::Handle<v8::Integer> Accessor::Info::query(v8::Local<v8::String> property) {
|
|
|
|
Accessor accessor(info->Data());
|
2012-05-23 00:06:21 -04:00
|
|
|
return v8::Integer::New(NUM2INT(rb_funcall(accessor.query, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this)));
|
2012-05-22 13:12:08 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
v8::Handle<v8::Boolean> Accessor::Info::remove(v8::Local<v8::String> property) {
|
|
|
|
Accessor accessor(info->Data());
|
|
|
|
return v8::Boolean::New(Bool(rb_funcall(accessor.deleter, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this)));
|
|
|
|
}
|
|
|
|
|
|
|
|
v8::Handle<v8::Array> Accessor::Info::enumerateNames() {
|
|
|
|
Accessor accessor(info->Data());
|
|
|
|
return Array(rb_funcall(accessor.enumerator, rb_intern("call"), 1, (VALUE)*this));
|
|
|
|
}
|
|
|
|
|
|
|
|
v8::Handle<v8::Value> Accessor::Info::get(uint32_t index) {
|
|
|
|
Accessor accessor(info->Data());
|
2012-06-12 05:17:43 -04:00
|
|
|
return Value(rb_funcall(accessor.get, rb_intern("call"), 2, UINT2NUM(index), (VALUE)*this));
|
2012-05-22 13:12:08 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
v8::Handle<v8::Value> Accessor::Info::set(uint32_t index, v8::Local<v8::Value> value) {
|
|
|
|
Accessor accessor(info->Data());
|
|
|
|
return Value(rb_funcall(accessor.set, rb_intern("call"), 3, UINT2NUM(index), (VALUE)Value(value), (VALUE)*this));
|
|
|
|
}
|
|
|
|
|
|
|
|
v8::Handle<v8::Integer> Accessor::Info::query(uint32_t index) {
|
|
|
|
Accessor accessor(info->Data());
|
2012-05-23 00:06:21 -04:00
|
|
|
return v8::Integer::New(NUM2INT(rb_funcall(accessor.query, rb_intern("call"), 2, UINT2NUM(index), (VALUE)*this)));
|
2012-05-22 13:12:08 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
v8::Handle<v8::Boolean> Accessor::Info::remove(uint32_t index) {
|
|
|
|
Accessor accessor(info->Data());
|
|
|
|
return v8::Boolean::New(Bool(rb_funcall(accessor.deleter, rb_intern("call"), 2, UINT2NUM(index), (VALUE)*this)));
|
|
|
|
}
|
|
|
|
|
|
|
|
v8::Handle<v8::Array> Accessor::Info::enumerateIndices() {
|
|
|
|
Accessor accessor(info->Data());
|
|
|
|
return Array(rb_funcall(accessor.enumerator, rb_intern("call"), 1, (VALUE)*this));
|
|
|
|
}
|
|
|
|
|
2012-05-21 17:36:19 -04:00
|
|
|
Accessor::Info::operator VALUE() {
|
|
|
|
return Data_Wrap_Struct(Class, 0, 0, (void*)this->info);
|
2012-05-09 14:12:44 -04:00
|
|
|
}
|
|
|
|
}
|