#ifndef EINA_JS_VALUE_HH #define EINA_JS_VALUE_HH #include #include namespace efl { namespace eina { namespace js { namespace detail { template struct is_representable_as_v8_integer: std::false_type {}; template struct is_representable_as_v8_integer ::value /* v8::Integer only stores 32-bit signed and unsigned numbers. */ && (sizeof(T) <= sizeof(int32_t))>::type> : std::true_type {}; template typename std::enable_if::value && std::is_signed::value, v8::Local>::type to_v8_number(const T &v, v8::Isolate *isolate) { return compatibility_new(isolate, v); } template typename std::enable_if::value && std::is_unsigned::value, v8::Local>::type to_v8_number(const T &v, v8::Isolate *isolate) { return compatibility_new(isolate, v); } template typename std::enable_if<(std::is_integral::value && !is_representable_as_v8_integer::value) || std::is_floating_point::value, v8::Local>::type to_v8_number(const T &v, v8::Isolate *isolate) { return compatibility_new(isolate, v); } template typename std::enable_if::value || std::is_same::value, v8::Local>::type to_v8_string(const T &v, v8::Isolate *isolate) { return compatibility_new(isolate, v.c_str()); } } // namespace detail template typename std::enable_if>::value, T>::type value_cast(const ::efl::eina::value &v, v8::Isolate *isolate) { using detail::to_v8_number; using detail::to_v8_string; using ::efl::eina::get; const auto &t = v.type_info(); if (t == EINA_VALUE_TYPE_UINT64) { return to_v8_number(get(v), isolate); } else if (t == EINA_VALUE_TYPE_UCHAR) { return to_v8_number(get(v), isolate); } else if (t == EINA_VALUE_TYPE_USHORT) { return to_v8_number(get(v), isolate); } else if (t == EINA_VALUE_TYPE_UINT) { return to_v8_number(get(v), isolate); } else if (t == EINA_VALUE_TYPE_ULONG) { return to_v8_number(get(v), isolate); } else if (t == EINA_VALUE_TYPE_CHAR) { return to_v8_number(get(v), isolate); } else if (t == EINA_VALUE_TYPE_SHORT) { return to_v8_number(get(v), isolate); } else if (t == EINA_VALUE_TYPE_INT) { return to_v8_number(get(v), isolate); } else if (t == EINA_VALUE_TYPE_LONG) { return to_v8_number(get(v), isolate); } else if (t == EINA_VALUE_TYPE_FLOAT) { return to_v8_number(get(v), isolate); } else if (t == EINA_VALUE_TYPE_DOUBLE) { return to_v8_number(get(v), isolate); } else if (t == EINA_VALUE_TYPE_STRINGSHARE) { return to_v8_string(get<::efl::eina::stringshare>(v), isolate); } else if (t == EINA_VALUE_TYPE_STRING) { return to_v8_string(get(v), isolate); } throw std::bad_cast{}; } template typename std::enable_if::value, T>::type value_cast(const v8::Handle &v) { using ::efl::eina::value; if (v->IsBoolean()) { return value(int{v->BooleanValue()}); } else if (v->IsInt32()) { return value(v->Int32Value()); } else if (v->IsUint32()) { return value(v->Uint32Value()); } else if (v->IsNumber()) { return value(v->NumberValue()); } else if (v->IsString()) { v8::String::Utf8Value data(v); return value(std::string(*data, data.length())); } throw std::bad_cast{}; } /* # JS binding - There is the `value()` constructor, which accepts a primitive value as input argument and might throw. - The returned object has a `get()` method, which can be used to get the wrapped value as a JavaScript value. - The returned object has a `set()` method, which can be used to change the wrapped value. */ void register_value(v8::Isolate *isolate, v8::Handle global, v8::Handle name); } } } // namespace efl::js EAPI void eina_value_register(v8::Handle global, v8::Isolate* isolate); #endif /* EINA_JS_VALUE_HH */