result_t util_base::clone(v8::Local<v8::Value> v, v8::Local<v8::Value> &retVal) { if (!v->IsProxy() && v->IsObject() && !object_base::getInstance(v)) { Isolate* isolate = Isolate::current(); if (v->IsFunction() || v->IsArgumentsObject() || v->IsSymbolObject()) retVal = v; else if (v->IsDate()) retVal = v8::Date::New(isolate->m_isolate, v->NumberValue()); else if (v->IsBooleanObject()) retVal = v8::BooleanObject::New(v->BooleanValue()); else if (v->IsNumberObject()) retVal = v8::NumberObject::New(isolate->m_isolate, v->NumberValue()); else if (v->IsStringObject()) retVal = v8::StringObject::New(v->ToString()); else if (v->IsRegExp()) { v8::Local<v8::RegExp> re = v8::Local<v8::RegExp>::Cast(v); retVal = v8::RegExp::New(re->GetSource(), re->GetFlags()); } else retVal = v8::Local<v8::Object>::Cast(v)->Clone(); } else retVal = v; return 0; }
// static CJS_Value::Type CJS_Value::GetValueType(v8::Local<v8::Value> value) { if (value.IsEmpty()) return VT_unknown; if (value->IsString()) return VT_string; if (value->IsNumber()) return VT_number; if (value->IsBoolean()) return VT_boolean; if (value->IsDate()) return VT_date; if (value->IsObject()) return VT_object; if (value->IsNull()) return VT_null; if (value->IsUndefined()) return VT_undefined; return VT_unknown; }
void _appendValue(exlib::string& str, v8::Local<v8::Value>& v, bool mysql) { bool bNumber = v->IsNumber() || v->IsNumberObject(); if (bNumber) { v8::String::Utf8Value s1(v); str.append(*s1, s1.length()); } else { exlib::string s; str += '\''; if (v->IsDate()) { date_t d = v; d.sqlString(s); } else { v8::String::Utf8Value s1(v); _escape(*s1, s1.length(), mysql, s); } str.append(s); str += '\''; } }
PJsonVal TNodeJsUtil::GetObjJson(const v8::Local<v8::Value>& Val, const bool IgnoreFunc) { AssertR(!Val->IsExternal(), "TNodeJsUtil::GetObjJson: Cannot parse v8::External!"); if (Val->IsObject()) { // if we aren't ignoring functions and the object is a function // then throw an exception EAssertR(IgnoreFunc || !Val->IsFunction(), "TNodeJsUtil::GetObjJson: Cannot parse functions!"); // parse the object if (Val->IsFunction()) { return TJsonVal::New(); } else if (Val->IsBooleanObject()) { v8::Local<v8::BooleanObject> BoolObj = v8::Local<v8::BooleanObject>::Cast(Val); return TJsonVal::NewBool(BoolObj->ValueOf()); } else if (Val->IsNumberObject()) { return TJsonVal::NewNum(Val->NumberValue()); } else if (Val->IsStringObject() || Val->IsRegExp() || Val->IsDate()) { return TJsonVal::NewStr(TStr(*v8::String::Utf8Value(Val->ToString()))); } else if (Val->IsArray()) { PJsonVal JsonArr = TJsonVal::NewArr(); v8::Array* Arr = v8::Array::Cast(*Val); for (uint i = 0; i < Arr->Length(); i++) { if (!IgnoreFunc || !Arr->Get(i)->IsFunction()) { JsonArr->AddToArr(GetObjJson(Arr->Get(i), IgnoreFunc)); } } return JsonArr; } else { // general object with fields PJsonVal JsonVal = TJsonVal::NewObj(); v8::Local<v8::Object> Obj = Val->ToObject(); v8::Local<v8::Array> FldNmV = Obj->GetOwnPropertyNames(); for (uint i = 0; i < FldNmV->Length(); i++) { const TStr FldNm(*v8::String::Utf8Value(FldNmV->Get(i)->ToString())); v8::Local<v8::Value> FldVal = Obj->Get(FldNmV->Get(i)); if (!IgnoreFunc || !FldVal->IsFunction()) { JsonVal->AddToObj(FldNm, GetObjJson(FldVal, IgnoreFunc)); } } return JsonVal; } } else { // primitive if (Val->IsUndefined()) { return TJsonVal::New(); } else if (Val->IsNull()) { return TJsonVal::NewNull(); } else if (Val->IsBoolean()) { return TJsonVal::NewBool(Val->BooleanValue()); } else if (Val->IsNumber()) { return TJsonVal::NewNum(Val->NumberValue()); } else if (Val->IsString()) { return TJsonVal::NewStr(TStr(*v8::String::Utf8Value(Val->ToString()))); } else { // TODO check for v8::Symbol throw TExcept::New("TNodeJsUtil::GetObjJson: Unknown v8::Primitive type!"); } } }
result_t util_base::isDate(v8::Local<v8::Value> v, bool& retVal) { retVal = v->IsDate(); return 0; }
// converts js value to java object and recursively converts sub objects if this // object is a container type jobject TypeConverter::jsValueToJavaObject(v8::Local<v8::Value> jsValue, bool *isNew) { JNIEnv *env = JNIScope::getEnv(); if (env == NULL) { return NULL; } if (jsValue->IsNumber()) { jdouble javaDouble = TypeConverter::jsNumberToJavaDouble(jsValue->ToNumber()); *isNew = true; return env->NewObject(JNIUtil::doubleClass, JNIUtil::doubleInitMethod, javaDouble); } else if (jsValue->IsBoolean()) { jboolean javaBoolean = TypeConverter::jsBooleanToJavaBoolean(jsValue->ToBoolean()); *isNew = true; return env->NewObject(JNIUtil::booleanClass, JNIUtil::booleanInitMethod, javaBoolean); } else if (jsValue->IsString()) { *isNew = true; return TypeConverter::jsStringToJavaString(jsValue->ToString()); } else if (jsValue->IsDate()) { Local<Date> date = Local<Date>::Cast<Value>(jsValue); return TypeConverter::jsDateToJavaDate(date); } else if (jsValue->IsArray()) { *isNew = true; return TypeConverter::jsArrayToJavaArray(v8::Handle<v8::Array>::Cast(jsValue)); } else if (jsValue->IsFunction()) { *isNew = true; return TypeConverter::jsObjectToJavaFunction(jsValue->ToObject()); } else if (jsValue->IsObject()) { v8::Handle<v8::Object> jsObject = jsValue->ToObject(); if (JavaObject::isJavaObject(jsObject)) { *isNew = JavaObject::useGlobalRefs ? false : true; JavaObject *javaObject = JavaObject::Unwrap<JavaObject>(jsObject); return javaObject->getJavaObject(); } else { v8::Handle<v8::Array> objectKeys = jsObject->GetOwnPropertyNames(); int numKeys = objectKeys->Length(); *isNew = true; jobject javaHashMap = env->NewObject(JNIUtil::hashMapClass, JNIUtil::hashMapInitMethod, numKeys); for (int i = 0; i < numKeys; i++) { v8::Local<v8::Value> jsObjectPropertyKey = objectKeys->Get((uint32_t) i); bool keyIsNew, valueIsNew; jobject javaObjectPropertyKey = TypeConverter::jsValueToJavaObject(jsObjectPropertyKey, &keyIsNew); v8::Local<v8::Value> jsObjectPropertyValue = jsObject->Get(jsObjectPropertyKey); jobject javaObjectPropertyValue = TypeConverter::jsValueToJavaObject(jsObjectPropertyValue, &valueIsNew); jobject result = env->CallObjectMethod(javaHashMap, JNIUtil::hashMapPutMethod, javaObjectPropertyKey, javaObjectPropertyValue); env->DeleteLocalRef(result); if (keyIsNew) { env->DeleteLocalRef(javaObjectPropertyKey); } if (valueIsNew) { env->DeleteLocalRef(javaObjectPropertyValue); } } return javaHashMap; } } LOGW(TAG, "jsValueToJavaObject returning null"); return NULL; }
jobject TypeConverter::jsValueToJavaObject(JNIEnv *env, v8::Local<v8::Value> jsValue, bool *isNew) { if (jsValue->IsNumber()) { *isNew = true; if (jsValue->IsInt32()) { jint javaInt = TypeConverter::jsNumberToJavaInt(jsValue->ToNumber()); return env->NewObject(JNIUtil::integerClass, JNIUtil::integerInitMethod, javaInt); } jdouble javaDouble = TypeConverter::jsNumberToJavaDouble(jsValue->ToNumber()); return env->NewObject(JNIUtil::doubleClass, JNIUtil::doubleInitMethod, javaDouble); } else if (jsValue->IsBoolean()) { jboolean javaBoolean = TypeConverter::jsBooleanToJavaBoolean(jsValue->ToBoolean()); *isNew = true; return env->NewObject(JNIUtil::booleanClass, JNIUtil::booleanInitMethod, javaBoolean); } else if (jsValue->IsString()) { *isNew = true; return TypeConverter::jsStringToJavaString(env, jsValue->ToString()); } else if (jsValue->IsDate()) { Local<Date> date = Local<Date>::Cast<Value>(jsValue); return TypeConverter::jsDateToJavaDate(env, date); } else if (jsValue->IsArray()) { *isNew = true; return TypeConverter::jsArrayToJavaArray(env, v8::Handle<v8::Array>::Cast(jsValue)); } else if (jsValue->IsFunction()) { *isNew = true; return TypeConverter::jsObjectToJavaFunction(env, jsValue->ToObject()); } else if (jsValue->IsObject()) { v8::Handle<v8::Object> jsObject = jsValue->ToObject(); if (JavaObject::isJavaObject(jsObject)) { *isNew = JavaObject::useGlobalRefs ? false : true; JavaObject *javaObject = JavaObject::Unwrap<JavaObject>(jsObject); return javaObject->getJavaObject(); } else { // Unwrap hyperloop JS wrappers to get native java proxy Handle<String> nativeString = String::New("$native"); if (jsObject->HasOwnProperty(nativeString)) { v8::Local<v8::Value> nativeObject = jsObject->GetRealNamedProperty(nativeString); jsObject = nativeObject->ToObject(); if (JavaObject::isJavaObject(jsObject)) { *isNew = JavaObject::useGlobalRefs ? false : true; JavaObject *javaObject = JavaObject::Unwrap<JavaObject>(jsObject); return javaObject->getJavaObject(); } } v8::Handle<v8::Array> objectKeys = jsObject->GetOwnPropertyNames(); int numKeys = objectKeys->Length(); *isNew = true; jobject javaHashMap = env->NewObject(JNIUtil::hashMapClass, JNIUtil::hashMapInitMethod, numKeys); for (int i = 0; i < numKeys; i++) { v8::Local<v8::Value> jsObjectPropertyKey = objectKeys->Get((uint32_t) i); bool keyIsNew, valueIsNew; jobject javaObjectPropertyKey = TypeConverter::jsValueToJavaObject(env, jsObjectPropertyKey, &keyIsNew); v8::Local<v8::Value> jsObjectPropertyValue = jsObject->Get(jsObjectPropertyKey); jobject javaObjectPropertyValue = TypeConverter::jsValueToJavaObject(env, jsObjectPropertyValue, &valueIsNew); jobject result = env->CallObjectMethod(javaHashMap, JNIUtil::hashMapPutMethod, javaObjectPropertyKey, javaObjectPropertyValue); env->DeleteLocalRef(result); if (keyIsNew) { env->DeleteLocalRef(javaObjectPropertyKey); } if (valueIsNew) { env->DeleteLocalRef(javaObjectPropertyValue); } } return javaHashMap; } } if (!jsValue->IsNull() && !jsValue->IsUndefined()) { LOGW(TAG, "jsValueToJavaObject returning null."); } return NULL; }
void encodeValue(bson *bb, const char *name, v8::Local<v8::Value> element, bool doJson) { if (element.IsEmpty() || element->IsUndefined() || element->IsFunction()) ; else if (element->IsNull()) bson_append_null(bb, name); else if (element->IsDate()) bson_append_date(bb, name, (bson_date_t) element->NumberValue()); else if (element->IsBoolean()) bson_append_bool(bb, name, element->IsTrue()); else if (element->IsNumber() || element->IsNumberObject()) { double value = element->NumberValue(); int64_t num = (int64_t) value; if (value == (double) num) { if (num >= -2147483648ll && num <= 2147483647ll) bson_append_int(bb, name, (int) num); else bson_append_long(bb, name, num); } else bson_append_double(bb, name, value); } else if (element->IsArray()) encodeArray(bb, name, element); else if (element->IsRegExp()) { v8::Local<v8::RegExp> re = v8::Local<v8::RegExp>::Cast(element); v8::Local<v8::String> src = re->GetSource(); v8::RegExp::Flags flgs = re->GetFlags(); char flgStr[4]; char *p = flgStr; if (flgs & v8::RegExp::kIgnoreCase) *p++ = 'i'; if (flgs & v8::RegExp::kGlobal) *p++ = 'g'; if (flgs & v8::RegExp::kMultiline) *p++ = 'm'; *p = 0; bson_append_regex(bb, name, *v8::String::Utf8Value(src), flgStr); } else if (element->IsObject()) { { obj_ptr<Int64> num = (Int64 *)Int64_base::getInstance(element); if (num) { if (num->m_num >= -2147483648ll && num->m_num <= 2147483647ll) bson_append_int(bb, name, (int) num->m_num); else bson_append_long(bb, name, num->m_num); return; } } { obj_ptr<Buffer_base> buf = Buffer_base::getInstance(element); if (buf) { std::string strBuf; buf->toString(strBuf); bson_append_binary(bb, name, BSON_BIN_BINARY, strBuf.c_str(), (int) strBuf.length()); return; } } { obj_ptr<MongoID> oid = (MongoID *) MongoID_base::getInstance( element); if (oid) { bson_append_oid(bb, name, &oid->m_id); return; } } encodeObject(bb, name, element, doJson); } else { v8::String::Utf8Value v(element); bson_append_string(bb, name, ToCString(v)); } }