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; }
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::isRegExp(v8::Local<v8::Value> v, bool& retVal) { retVal = v->IsRegExp(); return 0; }
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)); } }