#ifndef EFL_EINA_JS_GET_VALUE_HH #define EFL_EINA_JS_GET_VALUE_HH #include #include #include #include #include namespace efl { namespace eina { namespace js { template inline int get_value_from_javascript (v8::Local v , v8::Isolate* isolate , const char* , value_tag , bool throw_js_exception = true , typename std::enable_if<(std::is_integral::value && !std::is_same::value)>::type* = 0) { if(v->IsInt32()) return v->Int32Value(); else if(v->IsUint32()) return v->Uint32Value(); else { if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Type expected is different. Expected Integral type"))); throw std::logic_error(""); } return 0; } inline char* get_value_from_javascript (v8::Local v , v8::Isolate* isolate , const char* , value_tag , bool throw_js_exception = true) { if(v->IsNull()) return nullptr; else if(v->IsString()) { v8::String::Utf8Value str(v->ToString()); char* string = strdup(*str); // TODO: leaks return string; } else { if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Type expected is different. Expected String type"))); throw std::logic_error(""); } return 0; } inline const char* get_value_from_javascript (v8::Local v , v8::Isolate* isolate , const char* class_name , value_tag , bool throw_js_exception = true) { return get_value_from_javascript(v, isolate, class_name, value_tag(), throw_js_exception); } inline Eo* get_value_from_javascript (v8::Local v , v8::Isolate* isolate , const char* , value_tag , bool throw_js_exception = true) { if(v->IsNull()) return nullptr; else if(v->IsObject()) { v8::Local object = v->ToObject(); if(object->InternalFieldCount() == 1) { v8::Local r = object->GetInternalField(0); if(v8::External* external = v8::External::Cast(*r)) { return static_cast(external->Value()); } } } if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Type expected is different. Expected Eolian object type"))); throw std::logic_error(""); return nullptr; } inline Eo* get_value_from_javascript (v8::Local v , v8::Isolate* isolate , const char* class_name , value_tag , bool throw_js_exception = true) { return get_value_from_javascript(v, isolate, class_name, value_tag(), throw_js_exception); } // Futures template Eo* get_value_from_javascript (v8::Local , v8::Isolate* , const char* , value_tag> , bool = true) { throw std::logic_error(""); return nullptr; } template inline T get_value_from_javascript (v8::Local v , v8::Isolate* isolate , const char* , value_tag> , bool throw_js_exception = true) { if(v->IsNull()) return nullptr; else if(v->IsObject()) { v8::Local object = v->ToObject(); if(object->InternalFieldCount() == 1) { return compatibility_get_pointer_internal_field(object, 0); } } if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Type expected is different. Expected Eolian struct type"))); throw std::logic_error(""); return nullptr; } template inline T get_value_from_javascript (v8::Local v , v8::Isolate* isolate , const char* class_name , value_tag> , bool throw_js_exception = true) { T* ptr = get_value_from_javascript(v, isolate, class_name, value_tag>(), throw_js_exception); if (ptr) return *ptr; if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Conversion of null pointer to by-value struct."))); throw std::logic_error(""); return T{}; } template inline T get_value_from_javascript (v8::Local v , v8::Isolate* isolate , const char* , value_tag , bool throw_js_exception = true , typename std::enable_if::value>::type* = 0) { if(v->IsInt32()) return static_cast(v->Int32Value()); else if(v->IsUint32()) return static_cast(v->Uint32Value()); else { if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Type expected is different. Expected enumeration type"))); throw std::logic_error(""); } return T(); } inline Eina_Bool get_value_from_javascript (v8::Local v , v8::Isolate* isolate , const char* , value_tag , bool throw_js_exception = true) { if(v->IsBoolean() || v->IsBooleanObject()) { return v->BooleanValue() ? EINA_TRUE : EINA_FALSE; } else { if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Type expected is different. Expected Boolean type"))); throw std::logic_error(""); } return 0; } template inline double get_value_from_javascript (v8::Local v , v8::Isolate* isolate , const char* , value_tag , bool throw_js_exception = true , typename std::enable_if::value>::type* = 0) { if(v->IsNumber()) { return v->NumberValue(); } else { if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Type expected is different. Expected floating point type"))); throw std::logic_error(""); } return 0.0; } template inline T get_value_from_javascript (v8::Local, v8::Isolate* isolate, const char*, value_tag , bool throw_js_exception = true , typename std::enable_if< !std::is_floating_point::value && !std::is_integral::value && !std::is_enum::value && !js::is_struct_tag::value && !js::is_struct_ptr_tag::value && !js::is_complex_tag::value && !std::is_same::value && !std::is_same::value && !std::is_same::value && !std::is_same::value && !std::is_same::value && !std::is_same::value && !std::is_same::value && !std::is_same::value && !std::is_same::value && !std::is_same::value >::type* = 0) { if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Not implemented yet"))); throw std::logic_error(""); } // TODO: Fix for const types template inline Eina_Accessor* get_value_from_javascript( v8::Local v, v8::Isolate* isolate, const char*, value_tag>, bool throw_js_exception = true) { if(v->IsNull()) return nullptr; else if(v->IsObject()) { using wrapped_type = typename container_wrapper::type; v8::Local object = v->ToObject(); auto& acc = import_accessor(object); return acc.native_handle(); } if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Type expected is different. Expected Eolian accessor type"))); throw std::logic_error(""); } template inline const Eina_Accessor* get_value_from_javascript( v8::Local v, v8::Isolate* isolate, const char* class_name, value_tag>, bool throw_js_exception = true) { return get_value_from_javascript(v, isolate, class_name, value_tag>{}, throw_js_exception); } template inline Eina_Array* get_value_from_javascript( v8::Local v, v8::Isolate* isolate, const char*, value_tag>, bool throw_js_exception = true) { if(v->IsNull()) return nullptr; else if(v->IsObject()) { v8::Local object = v->ToObject(); if(object->InternalFieldCount() == 1) { eina_container_base* cbase = compatibility_get_pointer_internal_field(object, 0); return static_cast(cbase->get_container_native_handle()); } } if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Type expected is different. Expected Eolian list type"))); throw std::logic_error(""); return nullptr; } template inline const Eina_Array* get_value_from_javascript( v8::Local v, v8::Isolate* isolate, const char* class_name, value_tag>, bool throw_js_exception = true) { return get_value_from_javascript(v, isolate, class_name, value_tag>{}, throw_js_exception); } template inline Eina_Iterator* get_value_from_javascript( v8::Local v, v8::Isolate* isolate, const char*, value_tag> /*tag*/, bool throw_js_exception = true) { if(v->IsNull()) return nullptr; else if(v->IsObject()) { return import_iterator(v->ToObject()); } if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Type expected is different. Expected Eolian accessor type"))); throw std::logic_error(""); } template inline const Eina_Iterator* get_value_from_javascript( v8::Local v, v8::Isolate* isolate, const char* class_name, value_tag>, bool throw_js_exception = true) { return get_value_from_javascript(v, isolate, class_name, value_tag>{}, throw_js_exception); } template inline Eina_Hash* get_value_from_javascript( v8::Local, v8::Isolate* isolate, const char*, value_tag> tag, bool throw_js_exception = true) { if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Not implemented yet"))); throw std::logic_error(""); } template inline const Eina_Hash* get_value_from_javascript( v8::Local v, v8::Isolate* isolate, const char* class_name, value_tag>, bool throw_js_exception = true) { return get_value_from_javascript(v, isolate, class_name, value_tag>{}, throw_js_exception); } template inline Eina_List* get_value_from_javascript( v8::Local v, v8::Isolate* isolate, const char*, value_tag> /*tag*/, bool throw_js_exception = true) { if(v->IsNull()) return nullptr; else if(v->IsObject()) { v8::Local object = v->ToObject(); if(object->InternalFieldCount() == 1) { eina_container_base* cbase = compatibility_get_pointer_internal_field(object, 0); return static_cast(cbase->get_container_native_handle()); } } if (throw_js_exception) eina::js::compatibility_throw (isolate, v8::Exception::TypeError (eina::js::compatibility_new(isolate, "Type expected is different. Expected Eolian list type"))); throw std::logic_error(""); return nullptr; } template inline const Eina_List* get_value_from_javascript( v8::Local v, v8::Isolate* isolate, const char* class_name, value_tag>, bool throw_js_exception = true) { return get_value_from_javascript(v, isolate, class_name, value_tag>{}, throw_js_exception); } inline const void* get_value_from_javascript (v8::Local, v8::Isolate*, const char*, value_tag) { return nullptr; } typedef void (*Evas_Smart_Cb)(void*, _Eo_Opaque*, void*); inline Evas_Smart_Cb get_value_from_javascript ( v8::Local, v8::Isolate*, const char*, value_tag) { return nullptr; } } } } #endif