/*----------------------------------------------------------------------------- * Parse options */ bool ConnectParseOptions(Local<Object> options, ConnectRequest* request) { // Get options data std::vector<std::string> optionNames = cvv8::CastFromJS<std::vector<std::string> >(options->GetPropertyNames()); for (size_t i = 0; i < optionNames.size(); i++) { char* optionName = (char*)(optionNames[i].c_str()); Local<Value> optionValue = options->Get(String::NewSymbol(optionName)); if (optionValue->IsUndefined()) { continue; } if (tva_str_casecmp(optionName, "username") == 0) { String::AsciiValue val(optionValue->ToString()); request->username = strdup(*val); } else if (tva_str_casecmp(optionName, "password") == 0) { String::AsciiValue val(optionValue->ToString()); request->password = strdup(*val); } else if (tva_str_casecmp(optionName, "tmx") == 0) { if (optionValue->IsString()) { String::AsciiValue val(optionValue->ToString()); request->primaryTmx = strdup(*val); } else if (optionValue->IsArray()) { Handle<Array> tmxs = Handle<Array>::Cast(optionValue); char** p_tmx = &request->primaryTmx; Local<Value> element; element = tmxs->Get(0); if (!element->IsUndefined()) { String::AsciiValue tmx(element->ToString()); *p_tmx = strdup(*tmx); p_tmx = &request->secondaryTmx; } if (tmxs->Length() > 1) { element = tmxs->Get(1); if (!element->IsUndefined()) { String::AsciiValue tmx(element->ToString()); *p_tmx = strdup(*tmx); } } } } else if (tva_str_casecmp(optionName, "name") == 0) { String::AsciiValue val(optionValue->ToString()); request->gdClientName = strdup(*val); } else if (tva_str_casecmp(optionName, "timeout") == 0) { request->timeout = optionValue->Int32Value() * 1000; } else if (tva_str_casecmp(optionName, "gdMaxOut") == 0) { request->gdMaxOut = optionValue->Int32Value(); } else if (tva_str_casecmp(optionName, "config") == 0) { if (optionValue->IsObject()) { Local<Object> config = Local<Object>::Cast(optionValue); std::vector<std::string> configNames = cvv8::CastFromJS<std::vector<std::string> >(config->GetPropertyNames()); for (size_t j = 0; j < configNames.size(); j++) { char* configName = (char*)(configNames[j].c_str()); Local<Value> configValue = config->Get(String::NewSymbol(configName)); if (configValue->IsUndefined()) { continue; } for (size_t c = 0; c < NUM_PARAMS; c++) { ConnectConfigParam* cp = &g_connectConfig[c]; if (tva_str_casecmp(configName, cp->jsName) == 0) { switch (cp->configType) { case ConfigTypeBool: { bool bVal; if (configValue->IsBoolean()) { bVal = configValue->BooleanValue(); } else if (configValue->IsNumber()) { bVal = (configValue->NumberValue() != 0); } else if (configValue->IsString()) { String::AsciiValue bStrVal(config->ToString()); bVal = (tva_str_casecmp(*bStrVal, "true") == 0); } tvaAppCfgSet(cp->tvaParam, &bVal, (TVA_INT32)sizeof(bVal)); } break; case ConfigTypeInt: { int intVal = configValue->Int32Value(); tvaAppCfgSet(cp->tvaParam, &intVal, (TVA_INT32)sizeof(intVal)); } break; case ConfigTypeString: { String::AsciiValue strVal(configValue->ToString()); tvaAppCfgSet(cp->tvaParam, *strVal, (TVA_INT32)strlen(*strVal)); } break; case ConfigTypeCustom: if (cp->tvaParam == TVA_APPCFG_DATA_TRANSPORT_TYPE) { TVA_DATATRANSPORT_TYPE transportType = TVA_DATATRANSPORT_UDP; if (configValue->IsString()) { String::AsciiValue strVal(config->ToString()); if (tva_str_casecmp(*strVal, "TCP")) { transportType = TVA_DATATRANSPORT_TCP; } else if (tva_str_casecmp(*strVal, "SSL")) { transportType = TVA_DATATRANSPORT_SSL; } } else if (configValue->IsNumber()) { int numVal = (int)configValue->NumberValue(); if ((numVal == TVA_DATATRANSPORT_TCP) || (numVal == TVA_DATATRANSPORT_SSL)) { transportType = (TVA_DATATRANSPORT_TYPE)numVal; } } tvaAppCfgSet(cp->tvaParam, &transportType, (TVA_INT32)sizeof(transportType)); } break; } break; } } } } } } // Make sure required arguments were specified if (!request->username || !request->password || !request->primaryTmx) { return false; } return true; }
void ContactsPersonProxy::_setAddress(void* userContext, Handle<Value> value) { ContactsPersonProxy *obj = (ContactsPersonProxy*) userContext; if(!obj->isEditing) { obj->builder_ = obj->contact_.edit(); } // The value passed in *MUST* be an object containing arrays of objects // http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.Contacts.Person-property-address if(!value->IsObject()) return; // Get the JS Object and it's properties Local<Object> addressObject = value->ToObject(); Local<Array> addressProperties = addressObject->GetPropertyNames(); // Look for properties, such as "work", "home", or "other" for(int i = 0, len = addressProperties->Length(); i < len; i++) { // Get the key and value or each main object // { work: [ ... ] }" Local<String> addressKey = addressProperties->Get(i)->ToString(); Local<Value> addressValue = addressObject->Get(addressKey); // Create the subkind from the key of the object AttributeSubKind::Type subKind = AttributeSubKind::Other; QString _key = titanium::V8ValueToQString(addressKey); if(_key.toLower() == "work") { subKind = AttributeSubKind::Work; } if(_key.toLower() == "home") { subKind = AttributeSubKind::Home; } // The value of the individual address object *MUST* be an array of address objects // [ { street: '12 Main St' }, { street: '21 Meh St' } ] if(!addressValue->IsArray()) return; // Cast the value of the array to a v8 Array and look for addresses Local<Array> addresses = Local<Array>::Cast(addressValue); for(int i = 0, len = addresses->Length(); i < len; i++) { // Create the new address builder object and set the subkind ContactPostalAddressBuilder addressBuilder; addressBuilder.setSubKind(subKind); // Get the actual address object from the array of address objects // This *MUST* be an object with keys and values // { street: '12 Main St' } Local<Value> currentAddress = addresses->Get(Number::New(i)); if(!currentAddress->IsObject()) return; // Get the individual address object and look for it's properties Local<Object> currentAddressObject = currentAddress->ToObject(); Local<Array> currentAddressProperties = currentAddressObject->GetPropertyNames(); // Go through the keys and value of this object, one at a time for(int i = 0, len = currentAddressProperties->Length(); i < len; i++) { Local<String> currentAddressKey = currentAddressProperties->Get(i)->ToString(); Local<Value> currentAddressValue = currentAddressObject->Get(currentAddressKey); // The value *MUST* be a string if(!currentAddressValue->IsString()) return; // Cast it to a String and get the UTF8 strings Local<String> currentAddressStringValue = currentAddressValue->ToString(); // Convert them to QStrings for better manipulation QString _key = titanium::V8ValueToQString(currentAddressKey); QString _value = titanium::V8ValueToQString(currentAddressStringValue); // Start populating the address builder if(_key.toLower() == "city"){ addressBuilder.setCity(_value); } if(_key.toLower() == "label"){ addressBuilder.setLabel(_value); } if(_key.toLower() == "line1"){ addressBuilder.setLine1(_value); } if(_key.toLower() == "line2") { addressBuilder.setLine2(_value); } if(_key.toLower() == "street") { if(_value.contains("\n")) { QStringList l = _value.split('\n'); addressBuilder.setLine1(l.at(0)); l.removeAt(0); addressBuilder.setLine2(l.join("")); } else { addressBuilder.setLine1(_value); } } if(_key.toLower() == "zip"){ addressBuilder.setPostalCode(_value); } if(_key.toLower() == "county"){ addressBuilder.setRegion(_value); } if(_key.toLower() == "country"){ addressBuilder.setCountry(_value); } } // Once finished with an address, add it to the contact obj->builder_.addPostalAddress(addressBuilder); } } // Once done, update the contact if(!obj->isEditing) { ContactService().updateContact(obj->contact_); } }
void ArrayElementAccessor::SetArrayElement(const Local<Object>& array, uint32_t index, const string& arraySignature, Local<Value>& value) { JEnv env; Isolate* isolate = Isolate::GetCurrent(); HandleScope handleScope(isolate); jweak arr = objectManager->GetJavaObjectByJsObject(array); const string elementSignature = arraySignature.substr(1); jboolean isCopy = false; if (elementSignature == "Z") //bool { jboolean boolElementValue = (jboolean) value->BooleanValue(); jbooleanArray boolArr = reinterpret_cast<jbooleanArray>(arr); env.SetBooleanArrayRegion(boolArr, index, 1, &boolElementValue); } else if (elementSignature == "B") //byte { jbyte byteElementValue = (jbyte) value->Int32Value(); jbyteArray byteArr = reinterpret_cast<jbyteArray>(arr); env.SetByteArrayRegion(byteArr, index, 1, &byteElementValue); } else if (elementSignature == "C") //char { String::Utf8Value utf8(value->ToString()); JniLocalRef s(env.NewString((jchar*) *utf8, 1)); const char* singleChar = env.GetStringUTFChars(s, &isCopy); jchar charElementValue = *singleChar; env.ReleaseStringUTFChars(s, singleChar); jcharArray charArr = reinterpret_cast<jcharArray>(arr); env.SetCharArrayRegion(charArr, index, 1, &charElementValue); } else if (elementSignature == "S") //short { jshort shortElementValue = (jshort) value->Int32Value(); jshortArray shortArr = reinterpret_cast<jshortArray>(arr); env.SetShortArrayRegion(shortArr, index, 1, &shortElementValue); } else if (elementSignature == "I") //int { jint intElementValue = value->Int32Value(); jintArray intArr = reinterpret_cast<jintArray>(arr); env.SetIntArrayRegion(intArr, index, 1, &intElementValue); } else if (elementSignature == "J") //long { jlong longElementValue; if (value->IsObject()) { longElementValue = (jlong) ArgConverter::ConvertToJavaLong(value); } else { longElementValue = (jlong) value->IntegerValue(); } jlongArray longArr = reinterpret_cast<jlongArray>(arr); env.SetLongArrayRegion(longArr, index, 1, &longElementValue); } else if (elementSignature == "F") //float { jfloat floatElementValue = (jfloat) value->NumberValue(); jfloatArray floatArr = reinterpret_cast<jfloatArray>(arr); env.SetFloatArrayRegion(floatArr, index, 1, &floatElementValue); } else if (elementSignature == "D") //double { jdouble doubleElementValue = (jdouble) value->NumberValue(); jdoubleArray doubleArr = reinterpret_cast<jdoubleArray>(arr); env.SetDoubleArrayRegion(doubleArr, index, 1, &doubleElementValue); } else //string or object { bool isReferenceType = value->IsObject() || value->IsString(); if (isReferenceType) { auto object = value.As<Object>(); JsArgToArrayConverter argConverter(value, false, (int)Type::Null); if (argConverter.IsValid()) { jobjectArray objArr = reinterpret_cast<jobjectArray>(arr); jobject objectElementValue = argConverter.GetConvertedArg(); env.SetObjectArrayElement(objArr, index, objectElementValue); } else { JsArgToArrayConverter::Error err = argConverter.GetError(); throw NativeScriptException(string(err.msg)); } } else { throw NativeScriptException(string("Cannot assign primitive value to array of objects.")); } } }
getdns_dict* GNUtil::convertToDict(Local<Object> obj) { if (obj->IsRegExp() || obj->IsDate() || obj->IsFunction() || obj->IsUndefined() || obj->IsNull() || obj->IsArray()) { return NULL; } Local<Array> names = obj->GetOwnPropertyNames(); getdns_dict* result = getdns_dict_create(); for(unsigned int i = 0; i < names->Length(); i++) { Local<Value> nameVal = names->Get(i); Nan::Utf8String name(nameVal); Local<Value> val = obj->Get(nameVal); GetdnsType type = getGetdnsType(val); switch (type) { case IntType: getdns_dict_set_int(result, *name, val->ToUint32()->Value()); break; case BoolType: if (val->IsTrue()) { getdns_dict_set_int(result, *name, GETDNS_EXTENSION_TRUE); } else { getdns_dict_set_int(result, *name, GETDNS_EXTENSION_FALSE); } break; case StringType: { struct getdns_bindata strdata; String::Utf8Value utf8Str(val->ToString()); int len = utf8Str.length(); strdata.data = (uint8_t*) *utf8Str; strdata.size = len; getdns_dict_set_bindata(result, *name, &strdata); } break; case BinDataType: { struct getdns_bindata bdata; bdata.data = (uint8_t*) node::Buffer::Data(val); bdata.size = node::Buffer::Length(val); getdns_dict_set_bindata(result, *name, &bdata); } break; case ListType: { Local<Array> subArray = Local<Array>::Cast(val); struct getdns_list* sublist = GNUtil::convertToList(subArray); getdns_dict_set_list(result, *name, sublist); getdns_list_destroy(sublist); } break; case DictType: { Local<Object> subObj = val->ToObject(); struct getdns_dict* subdict = GNUtil::convertToDict(subObj); if (subdict) { getdns_dict_set_dict(result, *name, subdict); getdns_dict_destroy(subdict); } } break; default: break; } } return result; }
void ExecuteBaton::GetVectorParam(ExecuteBaton* baton, arrayParam_t* arrParam, Local<Array> arr) { // In case the array is empty just initialize the fields as we would need something in Connection::SetValuesOnStatement if (arr->Length() < 1) { arrParam->value = new int[0]; arrParam->collectionLength = 0; arrParam->elementsSize = 0; arrParam->elementLength = new ub2[0]; arrParam->elementsType = oracle::occi::OCCIINT; return; } // Next we create the array buffer that will be used later as the value for the param (in Connection::SetValuesOnStatement) // The array type will be derived from the type of the first element. Local<Value> val = arr->Get(0); // String array if (val->IsString()) { arrParam->elementsType = oracle::occi::OCCI_SQLT_STR; // Find the longest string, this is necessary in order to create a buffer later. int longestString = 0; for(unsigned int i = 0; i < arr->Length(); i++) { Local<Value> currVal = arr->Get(i); if (currVal->ToString()->Utf8Length() > longestString) longestString = currVal->ToString()->Utf8Length(); } // Add 1 for '\0' ++longestString; // Create a long char* that will hold the entire array, it is important to create a FIXED SIZE array, // meaning all strings have the same allocated length. char* strArr = new char[arr->Length() * longestString]; arrParam->elementLength = new ub2[arr->Length()]; // loop thru the arr and copy the strings into the strArr int bytesWritten = 0; for(unsigned int i = 0; i < arr->Length(); i++) { Local<Value> currVal = arr->Get(i); if(!currVal->IsString()) { std::ostringstream message; message << "Input array has object with invalid type at index " << i << ", all object must be of type 'string' which is the type of the first element"; baton->error = new std::string(message.str()); return; } String::Utf8Value utfStr(currVal); // Copy this string onto the strArr (we put \0 in the beginning as this is what strcat expects). strArr[bytesWritten] = '\0'; strncat(strArr + bytesWritten, *utfStr, longestString); bytesWritten += longestString; // Set the length of this element, add +1 for the '\0' arrParam->elementLength[i] = utfStr.length() + 1; } arrParam->value = strArr; arrParam->collectionLength = arr->Length(); arrParam->elementsSize = longestString; } // Integer array. else if (val->IsNumber()) { arrParam->elementsType = oracle::occi::OCCI_SQLT_NUM; // Allocate memory for the numbers array, Number in Oracle is 21 bytes unsigned char* numArr = new unsigned char[arr->Length() * 21]; arrParam->elementLength = new ub2[arr->Length()]; for(unsigned int i = 0; i < arr->Length(); i++) { Local<Value> currVal = arr->Get(i); if(!currVal->IsNumber()) { std::ostringstream message; message << "Input array has object with invalid type at index " << i << ", all object must be of type 'number' which is the type of the first element"; baton->error = new std::string(message.str()); return; } // JS numbers can exceed oracle numbers, make sure this is not the case. double d = currVal->ToNumber()->Value(); if (d > 9.99999999999999999999999999999999999999*std::pow(double(10), double(125)) || d < -9.99999999999999999999999999999999999999*std::pow(double(10), double(125))) { std::ostringstream message; message << "Input array has number that is out of the range of Oracle numbers, check the number at index " << i; baton->error = new std::string(message.str()); return; } // Convert the JS number into Oracle Number and get its bytes representation oracle::occi::Number n = d; oracle::occi::Bytes b = n.toBytes(); arrParam->elementLength[i] = b.length (); b.getBytes(&numArr[i*21], b.length()); } arrParam->value = numArr; arrParam->collectionLength = arr->Length(); arrParam->elementsSize = 21; } // Unsupported type else { baton->error = new std::string("The type of the first element in the input array is not supported"); } }
bool QueryOperation::BindParameters( Handle<Array> node_params ) { uint32_t count = node_params->Length(); if( count > 0 ) { for( uint32_t i = 0; i < count; ++i ) { Local<Value> p = node_params->Get( i ); ParamBinding binding; if( p->IsNull() ) { binding.js_type = ParamBinding::JS_NULL; binding.c_type = SQL_C_CHAR; binding.sql_type = SQL_CHAR; binding.param_size = 1; binding.digits = 0; binding.buffer = NULL; binding.buffer_len = 0; binding.indptr = SQL_NULL_DATA; } else if( p->IsString() ) { binding.js_type = ParamBinding::JS_STRING; binding.c_type = SQL_C_WCHAR; binding.sql_type = SQL_WVARCHAR; Local<String> str_param = p->ToString(); int str_len = str_param->Length(); binding.buffer = new uint16_t[ str_len + 1 ]; // null terminator str_param->Write( static_cast<uint16_t*>( binding.buffer )); if( str_len > 4000 ) { binding.param_size = 0; // max types require 0 precision } else { binding.param_size = str_len; } binding.buffer_len = str_len * sizeof( uint16_t ); binding.digits = 0; binding.indptr = binding.buffer_len; } else if( p->IsBoolean() ) { binding.js_type = ParamBinding::JS_BOOLEAN; binding.c_type = SQL_C_BIT; binding.sql_type = SQL_BIT; binding.buffer = new uint16_t; binding.buffer_len = sizeof( uint16_t ); *static_cast<uint16_t*>( binding.buffer ) = p->BooleanValue(); binding.param_size = 1; binding.digits = 0; binding.indptr = binding.buffer_len; } else if( p->IsInt32()) { binding.js_type = ParamBinding::JS_INT; binding.c_type = SQL_C_SLONG; binding.sql_type = SQL_INTEGER; binding.buffer = new int32_t; binding.buffer_len = sizeof( int32_t ); *static_cast<int32_t*>( binding.buffer ) = p->Int32Value(); binding.param_size = sizeof( int32_t ); binding.digits = 0; binding.indptr = binding.buffer_len; } else if( p->IsUint32()) { binding.js_type = ParamBinding::JS_UINT; binding.c_type = SQL_C_ULONG; binding.sql_type = SQL_BIGINT; binding.buffer = new uint32_t; binding.buffer_len = sizeof( uint32_t ); *static_cast<int32_t*>( binding.buffer ) = p->Uint32Value(); binding.param_size = sizeof( uint32_t ); binding.digits = 0; binding.indptr = binding.buffer_len; } else if( p->IsNumber()) { // numbers can be either integers or doubles. We attempt to determine which it is through a simple // cast and equality check double d = p->NumberValue(); if( _isnan( d ) || !_finite( d ) ) { return ParameterErrorToUserCallback( i, "Invalid number parameter" ); } else if( d == floor( d ) && d >= std::numeric_limits<int64_t>::min() && d <= std::numeric_limits<int64_t>::max() ) { binding.js_type = ParamBinding::JS_NUMBER; binding.c_type = SQL_C_SBIGINT; binding.sql_type = SQL_BIGINT; binding.buffer = new int64_t; binding.buffer_len = sizeof( int64_t ); *static_cast<int64_t*>( binding.buffer ) = p->IntegerValue(); binding.param_size = sizeof( int64_t ); binding.digits = 0; binding.indptr = binding.buffer_len; } else { binding.js_type = ParamBinding::JS_NUMBER; binding.c_type = SQL_C_DOUBLE; binding.sql_type = SQL_DOUBLE; binding.buffer = new double; binding.buffer_len = sizeof( double ); *static_cast<double*>( binding.buffer ) = p->NumberValue(); binding.param_size = sizeof( double ); binding.digits = 0; binding.indptr = binding.buffer_len; } } else if( p->IsDate() ) { // Since JS dates have no timezone context, all dates are assumed to be UTC Handle<Date> dateObject = Handle<Date>::Cast<Value>( p ); assert( !dateObject.IsEmpty() ); // dates in JS are stored internally as ms count from Jan 1, 1970 double d = dateObject->NumberValue(); SQL_SS_TIMESTAMPOFFSET_STRUCT* sql_tm = new SQL_SS_TIMESTAMPOFFSET_STRUCT; TimestampColumn sql_date( d ); sql_date.ToTimestampOffset( *sql_tm ); binding.js_type = ParamBinding::JS_DATE; binding.c_type = SQL_C_BINARY; // TODO: Determine proper SQL type based on version of server we're talking to binding.sql_type = SQL_SS_TIMESTAMPOFFSET; binding.buffer = sql_tm; binding.buffer_len = sizeof( SQL_SS_TIMESTAMPOFFSET_STRUCT ); // TODO: Determine proper precision and size based on version of server we're talking to binding.param_size = SQL_SERVER_2008_DEFAULT_DATETIME_PRECISION; binding.digits = SQL_SERVER_2008_DEFAULT_DATETIME_SCALE; binding.indptr = binding.buffer_len; } else if( p->IsObject() && node::Buffer::HasInstance( p )) { // TODO: Determine if we need something to keep the Buffer object from going // away while we use it we could just copy the data, but with buffers being // potentially very large, that could be problematic Local<Object> o = p.As<Object>(); binding.js_type = ParamBinding::JS_BUFFER; binding.c_type = SQL_C_BINARY; binding.sql_type = SQL_VARBINARY; binding.buffer = node::Buffer::Data( o ); binding.buffer_len = node::Buffer::Length( o ); binding.param_size = binding.buffer_len; binding.digits = 0; binding.indptr = binding.buffer_len; } else { return ParameterErrorToUserCallback( i, "Invalid parameter type" ); } params.push_back( move( binding )); } } return true; }
void Proxy::onPropertyChanged(Local<Name> property, Local<Value> value, const v8::PropertyCallbackInfo<void>& info) { Isolate* isolate = info.GetIsolate(); onPropertyChangedForProxy(isolate, property->ToString(isolate), value, info.Holder()); }
void FieldAccessor::SetJavaField(const Local<Object>& target, const Local<Value>& value, FieldCallbackData *fieldData) { JEnv env; auto isolate = Isolate::GetCurrent(); HandleScope handleScope(isolate); jweak targetJavaObject; const auto& fieldTypeName = fieldData->signature; auto isStatic = fieldData->isStatic; auto isPrimitiveType = fieldTypeName.size() == 1; auto isFieldArray = fieldTypeName[0] == '['; if (fieldData->fid == nullptr) { auto fieldJniSig = isPrimitiveType ? fieldTypeName : (isFieldArray ? fieldTypeName : ("L" + fieldTypeName + ";")); if (isStatic) { fieldData->clazz = env.FindClass(fieldData->declaringType); assert(fieldData->clazz != nullptr); fieldData->fid = env.GetStaticFieldID(fieldData->clazz, fieldData->name, fieldJniSig); assert(fieldData->fid != nullptr); } else { fieldData->clazz = env.FindClass(fieldData->declaringType); assert(fieldData->clazz != nullptr); fieldData->fid = env.GetFieldID(fieldData->clazz, fieldData->name, fieldJniSig); assert(fieldData->fid != nullptr); } } if (!isStatic) { targetJavaObject = objectManager->GetJavaObjectByJsObject(target); } auto fieldId = fieldData->fid; auto clazz = fieldData->clazz; if (isPrimitiveType) { switch (fieldTypeName[0]) { case 'Z': //bool { //TODO: validate value is a boolean before calling if (isStatic) { env.SetStaticBooleanField(clazz, fieldId, value->BooleanValue()); } else { env.SetBooleanField(targetJavaObject, fieldId, value->BooleanValue()); } break; } case 'B': //byte { //TODO: validate value is a byte before calling if (isStatic) { env.SetStaticByteField(clazz, fieldId, value->Int32Value()); } else { env.SetByteField(targetJavaObject, fieldId, value->Int32Value()); } break; } case 'C': //char { //TODO: validate value is a single char String::Utf8Value stringValue(value->ToString()); JniLocalRef value(env.NewStringUTF(*stringValue)); const char* chars = env.GetStringUTFChars(value, 0); if (isStatic) { env.SetStaticCharField(clazz, fieldId, chars[0]); } else { env.SetCharField(targetJavaObject, fieldId, chars[0]); } env.ReleaseStringUTFChars(value, chars); break; } case 'S': //short { //TODO: validate value is a short before calling if (isStatic) { env.SetStaticShortField(clazz, fieldId, value->Int32Value()); } else { env.SetShortField(targetJavaObject, fieldId, value->Int32Value()); } break; } case 'I': //int { //TODO: validate value is a int before calling if (isStatic) { env.SetStaticIntField(clazz, fieldId, value->Int32Value()); } else { env.SetIntField(targetJavaObject, fieldId, value->Int32Value()); } break; } case 'J': //long { jlong longValue = static_cast<jlong>(ArgConverter::ConvertToJavaLong(value)); if (isStatic) { env.SetStaticLongField(clazz, fieldId, longValue); } else { env.SetLongField(targetJavaObject, fieldId, longValue); } break; } case 'F': //float { if (isStatic) { env.SetStaticFloatField(clazz, fieldId, static_cast<jfloat>(value->NumberValue())); } else { env.SetFloatField(targetJavaObject, fieldId, static_cast<jfloat>(value->NumberValue())); } break; } case 'D': //double { if (isStatic) { env.SetStaticDoubleField(clazz, fieldId, value->NumberValue()); } else { env.SetDoubleField(targetJavaObject, fieldId, value->NumberValue()); } break; } default: { // TODO: ASSERT_FAIL("Unknown field type"); break; } } } else { bool isString = fieldTypeName == "java/lang/String"; jobject result = nullptr; if(!value->IsNull()) { if (isString) { //TODO: validate valie is a string; result = ConvertToJavaString(value); } else { auto objectWithHiddenID = value->ToObject(); result =objectManager->GetJavaObjectByJsObject(objectWithHiddenID); } } if (isStatic) { env.SetStaticObjectField(clazz, fieldId, result); } else { env.SetObjectField(targetJavaObject, fieldId, result); } if (isString) { env.DeleteLocalRef(result); } } }
void JNIV8ClassInfo::v8JavaAccessorSetterCallback(Local<Name> property, Local<Value> value, const PropertyCallbackInfo<void> &info) { JNIEnv *env = JNIWrapper::getEnvironment(); JNILocalFrame localFrame(env, 1); Isolate *isolate = info.GetIsolate(); HandleScope scope(isolate); v8::Local<v8::External> ext; ext = info.Data().As<v8::External>(); JNIV8ObjectJavaAccessorHolder* cb = static_cast<JNIV8ObjectJavaAccessorHolder*>(ext->Value()); if (cb->javaSetterId) { jobject jobj = nullptr; jvalue jval; memset(&jval, 0, sizeof(jvalue)); if (!cb->isStatic) { ext = info.This()->GetInternalField(0).As<v8::External>(); JNIV8Object *v8Object = reinterpret_cast<JNIV8Object *>(ext->Value()); jobj = v8Object->getJObject(); } JNIV8MarshallingError res; res = JNIV8Marshalling::convertV8ValueToJavaValue(env, value, cb->propertyType, &jval); if(res != JNIV8MarshallingError::kOk) { switch(res) { default: case JNIV8MarshallingError::kWrongType: ThrowV8TypeError("wrong type for property '" + cb->propertyName); break; case JNIV8MarshallingError::kUndefined: ThrowV8TypeError("property '" + cb->propertyName + "' must not be undefined"); break; case JNIV8MarshallingError::kNotNullable: ThrowV8TypeError("property '" + cb->propertyName + "' is not nullable"); break; case JNIV8MarshallingError::kNoNaN: ThrowV8TypeError("property '" + cb->propertyName + "' must not be NaN"); break; case JNIV8MarshallingError::kVoidNotNull: ThrowV8TypeError("property '" + cb->propertyName + "' can only be null or undefined"); break; case JNIV8MarshallingError::kOutOfRange: ThrowV8RangeError("assigned value '"+ JNIV8Marshalling::v8string2string(value->ToString(isolate))+"' is out of range for property '" + cb->propertyName + "'"); break; } return; } if (jobj) { env->CallVoidMethodA(jobj, cb->javaSetterId, &jval); } else { env->CallStaticVoidMethodA(cb->javaClass, cb->javaSetterId, &jval); } // java method could have thrown an exception; if so forward it to v8 if(env->ExceptionCheck()) { BGJSV8Engine::GetInstance(isolate)->forwardJNIExceptionToV8(); return; } } }
void Proxy::setProperty(Local<Name> property, Local<Value> value, const PropertyCallbackInfo<void>& info) { Isolate* isolate = info.GetIsolate(); setPropertyOnProxy(isolate, property->ToString(isolate), value, info.This()); }
jobject JNIV8Object::jniGetV8Fields(JNIEnv *env, jobject obj, jboolean ownOnly, jint flags, jint type, jclass returnType) { JNIV8Object_PrepareJNICall(JNIV8Object, Object, nullptr); JNIV8JavaValue arg = JNIV8Marshalling::valueWithClass(type, returnType, (JNIV8MarshallingFlags)flags); MaybeLocal<Array> maybeArrayRef = ownOnly ? localRef->GetOwnPropertyNames(context) : localRef->GetPropertyNames(context); if(maybeArrayRef.IsEmpty()) { ptr->getEngine()->forwardV8ExceptionToJNI(&try_catch); return nullptr; } Local<Array> arrayRef = maybeArrayRef.ToLocalChecked(); Local<Value> valueRef; Local<String> keyRef; jobject strObj; // we are only using the .l member of the jvalue; so one memset is enough! jvalue jval = {0}; memset(&jval, 0, sizeof(jvalue)); jobject result = env->NewObject(_jniHashMap.clazz, _jniHashMap.initId); for(uint32_t i=0,n=arrayRef->Length(); i<n; i++) { MaybeLocal<Value> maybeValueRef = arrayRef->Get(context, i); if(!maybeValueRef.ToLocal<Value>(&valueRef)) { ptr->getEngine()->forwardV8ExceptionToJNI(&try_catch); return nullptr; } keyRef = valueRef->ToString(isolate); maybeValueRef = localRef->Get(context, keyRef); if(!maybeValueRef.ToLocal<Value>(&valueRef)) { ptr->getEngine()->forwardV8ExceptionToJNI(&try_catch); return nullptr; } JNIV8MarshallingError res = JNIV8Marshalling::convertV8ValueToJavaValue(env, valueRef, arg, &jval); if(res != JNIV8MarshallingError::kOk) { std::string strPropertyName = JNIV8Marshalling::v8string2string(keyRef); switch(res) { default: case JNIV8MarshallingError::kWrongType: ThrowJNICastError("wrong type for value of '" + strPropertyName + "'"); break; case JNIV8MarshallingError::kUndefined: ThrowJNICastError("value of '" + strPropertyName + "' must not be undefined"); break; case JNIV8MarshallingError::kNotNullable: ThrowJNICastError("value of '" + strPropertyName + "' is not nullable"); break; case JNIV8MarshallingError::kNoNaN: ThrowJNICastError("value of '" + strPropertyName + "' must not be NaN"); break; case JNIV8MarshallingError::kVoidNotNull: ThrowJNICastError("value of '" + strPropertyName + "' can only be null or undefined"); break; case JNIV8MarshallingError::kOutOfRange: ThrowJNICastError("value '"+ JNIV8Marshalling::v8string2string(valueRef->ToString(context).ToLocalChecked())+"' is out of range for property '" + strPropertyName + "'"); break; } return nullptr; } strObj = JNIV8Marshalling::v8string2jstring(keyRef); env->CallObjectMethod(result, _jniHashMap.putId, strObj, jval.l ); env->DeleteLocalRef(jval.l); env->DeleteLocalRef(strObj); } return result; }
jobject JNIV8Object::jniCallV8MethodWithReturnType(JNIEnv *env, jobject obj, jstring name, jint flags, jint type, jclass returnType, jobjectArray arguments) { JNIV8Object_PrepareJNICall(JNIV8Object, Object, nullptr); JNIV8JavaValue arg = JNIV8Marshalling::valueWithClass(type, returnType, (JNIV8MarshallingFlags)flags); MaybeLocal<Value> maybeLocal; Local<Value> funcRef; maybeLocal = localRef->Get(context, JNIV8Marshalling::jstring2v8string(name)); if (!maybeLocal.ToLocal<Value>(&funcRef)) { ptr->getEngine()->forwardV8ExceptionToJNI(&try_catch); return nullptr; } if(!funcRef->IsFunction()) { ptr = nullptr; // release shared_ptr before throwing an exception! env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), "Called v8 field is not a function"); return nullptr; } jsize numArgs; Local<Value> *args; jobject tempObj; numArgs = env->GetArrayLength(arguments); if (numArgs) { args = (Local<Value>*)malloc(sizeof(Local<Value>)*numArgs); for(jsize i=0; i<numArgs; i++) { tempObj = env->GetObjectArrayElement(arguments, i); args[i] = JNIV8Marshalling::jobject2v8value(tempObj); env->DeleteLocalRef(tempObj); } } else { args = nullptr; } Local<Value> resultRef; maybeLocal = Local<Object>::Cast(funcRef)->CallAsFunction(context, localRef, numArgs, args); if (!maybeLocal.ToLocal<Value>(&resultRef)) { ptr->getEngine()->forwardV8ExceptionToJNI(&try_catch); return nullptr; } if(args) { free(args); } jvalue jval; memset(&jval, 0, sizeof(jvalue)); JNIV8MarshallingError res = JNIV8Marshalling::convertV8ValueToJavaValue(env, resultRef, arg, &jval); if(res != JNIV8MarshallingError::kOk) { std::string strMethodName = JNIWrapper::jstring2string(name); switch(res) { default: case JNIV8MarshallingError::kWrongType: ThrowJNICastError("wrong type for return value of '" + strMethodName + "'"); break; case JNIV8MarshallingError::kUndefined: ThrowJNICastError("return value of '" + strMethodName + "' must not be undefined"); break; case JNIV8MarshallingError::kNotNullable: ThrowJNICastError("return value of '" + strMethodName + "' is not nullable"); break; case JNIV8MarshallingError::kNoNaN: ThrowJNICastError("return value of '" + strMethodName + "' must not be NaN"); break; case JNIV8MarshallingError::kVoidNotNull: ThrowJNICastError("return value of '" + strMethodName + "' can only be null or undefined"); break; case JNIV8MarshallingError::kOutOfRange: ThrowJNICastError("return value '"+ JNIV8Marshalling::v8string2string(resultRef->ToString(context).ToLocalChecked())+"' is out of range for method '" + strMethodName + "'"); break; } return nullptr; } return jval.l; }
Parameter* ODBC::GetParametersFromArray (Local<Array> values, int *paramCount) { DEBUG_PRINTF("ODBC::GetParametersFromArray\n"); *paramCount = values->Length(); Parameter* params = NULL; if (*paramCount > 0) { params = (Parameter *) malloc(*paramCount * sizeof(Parameter)); } for (int i = 0; i < *paramCount; i++) { Local<Value> value = values->Get(i); params[i].ColumnSize = 0; params[i].StrLen_or_IndPtr = SQL_NULL_DATA; params[i].BufferLength = 0; params[i].DecimalDigits = 0; DEBUG_PRINTF("ODBC::GetParametersFromArray - param[%i].length = %lli\n", i, params[i].StrLen_or_IndPtr); if (value->IsString()) { Local<String> string = value->ToString(); int length = string->Length(); params[i].ValueType = SQL_C_TCHAR; params[i].ColumnSize = 0; //SQL_SS_LENGTH_UNLIMITED #ifdef UNICODE params[i].ParameterType = SQL_WVARCHAR; params[i].BufferLength = (length * sizeof(uint16_t)) + sizeof(uint16_t); #else params[i].ParameterType = SQL_VARCHAR; params[i].BufferLength = string->Utf8Length() + 1; #endif params[i].ParameterValuePtr = malloc(params[i].BufferLength); params[i].StrLen_or_IndPtr = SQL_NTS;//params[i].BufferLength; #ifdef UNICODE string->Write((uint16_t *) params[i].ParameterValuePtr); #else string->WriteUtf8((char *) params[i].ParameterValuePtr); #endif DEBUG_PRINTF("ODBC::GetParametersFromArray - IsString(): params[%i] c_type=%i type=%i buffer_length=%lli size=%lli length=%lli value=%s\n", i, params[i].ValueType, params[i].ParameterType, params[i].BufferLength, params[i].ColumnSize, params[i].StrLen_or_IndPtr, (char*) params[i].ParameterValuePtr); } else if (value->IsNull()) { params[i].ValueType = SQL_C_DEFAULT; params[i].ParameterType = SQL_VARCHAR; params[i].StrLen_or_IndPtr = SQL_NULL_DATA; DEBUG_PRINTF("ODBC::GetParametersFromArray - IsNull(): params[%i] c_type=%i type=%i buffer_length=%lli size=%lli length=%lli\n", i, params[i].ValueType, params[i].ParameterType, params[i].BufferLength, params[i].ColumnSize, params[i].StrLen_or_IndPtr); } else if (value->IsInt32()) { int64_t *number = new int64_t(value->IntegerValue()); params[i].ValueType = SQL_C_SBIGINT; params[i].ParameterType = SQL_BIGINT; params[i].ParameterValuePtr = number; params[i].StrLen_or_IndPtr = 0; DEBUG_PRINTF("ODBC::GetParametersFromArray - IsInt32(): params[%i] c_type=%i type=%i buffer_length=%lli size=%lli length=%lli value=%lld\n", i, params[i].ValueType, params[i].ParameterType, params[i].BufferLength, params[i].ColumnSize, params[i].StrLen_or_IndPtr, *number); } else if (value->IsNumber()) { double *number = new double(value->NumberValue()); params[i].ValueType = SQL_C_DOUBLE; params[i].ParameterType = SQL_DECIMAL; params[i].ParameterValuePtr = number; params[i].BufferLength = sizeof(double); params[i].StrLen_or_IndPtr = params[i].BufferLength; params[i].DecimalDigits = 7; params[i].ColumnSize = sizeof(double); DEBUG_PRINTF("ODBC::GetParametersFromArray - IsNumber(): params[%i] c_type=%i type=%i buffer_length=%lli size=%lli length=%lli value=%f\n", i, params[i].ValueType, params[i].ParameterType, params[i].BufferLength, params[i].ColumnSize, params[i].StrLen_or_IndPtr, *number); } else if (value->IsBoolean()) { bool *boolean = new bool(value->BooleanValue()); params[i].ValueType = SQL_C_BIT; params[i].ParameterType = SQL_BIT; params[i].ParameterValuePtr = boolean; params[i].StrLen_or_IndPtr = 0; DEBUG_PRINTF("ODBC::GetParametersFromArray - IsBoolean(): params[%i] c_type=%i type=%i buffer_length=%lli size=%lli length=%lli\n", i, params[i].ValueType, params[i].ParameterType, params[i].BufferLength, params[i].ColumnSize, params[i].StrLen_or_IndPtr); } } return params; }
Handle<Value> Session::Request(const Arguments& args) { HandleScope scope; if (args.Length() < 1 || !args[0]->IsString()) { return ThrowException(Exception::Error(String::New( "Service URI string must be provided as first parameter."))); } if (args.Length() < 2 || !args[1]->IsString()) { return ThrowException(Exception::Error(String::New( "String request name must be provided as second parameter."))); } if (args.Length() < 3 || !args[2]->IsObject()) { return ThrowException(Exception::Error(String::New( "Object containing request parameters must be provided " "as third parameter."))); } if (args.Length() < 4 || !args[3]->IsInt32()) { return ThrowException(Exception::Error(String::New( "Integer correlation identifier must be provided " "as fourth parameter."))); } if (args.Length() >= 5 && !args[4]->IsUndefined() && !args[4]->IsString()) { return ThrowException(Exception::Error(String::New( "Optional request label must be a string."))); } if (args.Length() > 5) { return ThrowException(Exception::Error(String::New( "Function expects at most five arguments."))); } int cidi = args[3]->Int32Value(); Session* session = ObjectWrap::Unwrap<Session>(args.This()); BLPAPI_EXCEPTION_TRY Local<String> uri = args[0]->ToString(); String::AsciiValue uriv(uri); blpapi::Service service = session->d_session->getService(*uriv); Local<String> name = args[1]->ToString(); String::Utf8Value namev(name); blpapi::Request request = service.createRequest(*namev); // Loop over object properties, appending/setting into the request. Local<Object> obj = args[2]->ToObject(); Local<Array> props = obj->GetPropertyNames(); for (std::size_t i = 0; i < props->Length(); ++i) { // Process the key. Local<Value> keyval = props->Get(i); Local<String> key = keyval->ToString(); String::Utf8Value keyv(key); // Process the value. // // The values present on the outer object are marshalled into the // blpapi::Request by setting values using 'set'. Arrays indicate // values which should be marshalled using 'append'. Local<Value> val = obj->Get(keyval); if (val->IsString()) { Local<String> s = val->ToString(); String::Utf8Value valv(s); request.set(*keyv, *valv); } else if (val->IsBoolean()) { request.set(*keyv, val->BooleanValue()); } else if (val->IsNumber()) { request.set(*keyv, val->NumberValue()); } else if (val->IsInt32()) { request.set(*keyv, val->Int32Value()); } else if (val->IsUint32()) { request.set(*keyv, static_cast<blpapi::Int64>(val->Uint32Value())); } else if (val->IsDate()) { blpapi::Datetime dt; mkdatetime(&dt, val); request.set(*keyv, dt); } else if (val->IsArray()) { // Arrays are marshalled into the blpapi::Request by appending // value types using the key of the array in the outer object. Local<Object> subarray = val->ToObject(); int jmax = Array::Cast(*val)->Length(); for (int j = 0; j < jmax; ++j) { Local<Value> subval = subarray->Get(j); // Only strings, booleans, and numbers are marshalled. if (subval->IsString()) { Local<String> s = subval->ToString(); String::Utf8Value subvalv(s); request.append(*keyv, *subvalv); } else if (subval->IsBoolean()) { request.append(*keyv, subval->BooleanValue()); } else if (subval->IsNumber()) { request.append(*keyv, subval->NumberValue()); } else if (subval->IsInt32()) { request.append(*keyv, subval->Int32Value()); } else if (subval->IsUint32()) { request.append(*keyv, static_cast<blpapi::Int64>(subval->Uint32Value())); } else if (subval->IsDate()) { blpapi::Datetime dt; mkdatetime(&dt, subval); request.append(*keyv, dt); } else { return ThrowException(Exception::Error(String::New( "Array contains invalid value type."))); } } } else { return ThrowException(Exception::Error(String::New( "Object contains invalid value type."))); } } blpapi::CorrelationId cid(cidi); if (args.Length() == 5) { String::Utf8Value labelv(args[4]->ToString()); session->d_session->sendRequest(request, session->d_identity, cid, 0, *labelv, labelv.length()); } else { session->d_session->sendRequest(request, session->d_identity, cid); } BLPAPI_EXCEPTION_CATCH_RETURN return scope.Close(Integer::New(cidi)); }
void Proxy::getProperty(Local<Name> property, const PropertyCallbackInfo<Value>& args) { Isolate* isolate = args.GetIsolate(); args.GetReturnValue().Set(getPropertyForProxy(isolate, property->ToString(isolate), args.Holder())); }
void Window::SetTitle(Local<String> property, Local<Value> value, const AccessorInfo& info) { NativeWindow *window = ObjectWrap::Unwrap<NativeWindow>(info.Holder()); window->SetTitle(V8StringToChar(value->ToString())); }
Parameter* ODBC::GetParametersFromArray (Local<Array> values, int *paramCount) { DEBUG_PRINTF("ODBC::GetParametersFromArray\n"); *paramCount = values->Length(); Parameter* params = (Parameter *) malloc(*paramCount * sizeof(Parameter)); for (int i = 0; i < *paramCount; i++) { Local<Value> value = values->Get(i); params[i].size = 0; params[i].length = SQL_NULL_DATA; params[i].buffer_length = 0; params[i].decimals = 0; DEBUG_PRINTF("ODBC::GetParametersFromArray - ¶m[%i].length = %X\n", i, ¶ms[i].length); if (value->IsString()) { Local<String> string = value->ToString(); int length = string->Length(); params[i].c_type = SQL_C_TCHAR; #ifdef UNICODE params[i].type = (length >= 8000) ? SQL_WLONGVARCHAR : SQL_WVARCHAR; params[i].buffer_length = (length * sizeof(uint16_t)) + sizeof(uint16_t); #else params[i].type = (length >= 8000) ? SQL_LONGVARCHAR : SQL_VARCHAR; params[i].buffer_length = string->Utf8Length() + 1; #endif params[i].buffer = malloc(params[i].buffer_length); params[i].size = params[i].buffer_length; params[i].length = SQL_NTS;//params[i].buffer_length; #ifdef UNICODE string->Write((uint16_t *) params[i].buffer); #else string->WriteUtf8((char *) params[i].buffer); #endif DEBUG_PRINTF("ODBC::GetParametersFromArray - IsString(): params[%i] " "c_type=%i type=%i buffer_length=%i size=%i length=%i " "value=%s\n", i, params[i].c_type, params[i].type, params[i].buffer_length, params[i].size, params[i].length, (char*) params[i].buffer); } else if (value->IsNull()) { params[i].c_type = SQL_C_DEFAULT; params[i].type = SQL_VARCHAR; params[i].length = SQL_NULL_DATA; DEBUG_PRINTF("ODBC::GetParametersFromArray - IsNull(): params[%i] " "c_type=%i type=%i buffer_length=%i size=%i length=%i\n", i, params[i].c_type, params[i].type, params[i].buffer_length, params[i].size, params[i].length); } else if (value->IsInt32()) { int64_t *number = new int64_t(value->IntegerValue()); params[i].c_type = SQL_C_SBIGINT; params[i].type = SQL_BIGINT; params[i].buffer = number; params[i].length = 0; DEBUG_PRINTF("ODBC::GetParametersFromArray - IsInt32(): params[%i] " "c_type=%i type=%i buffer_length=%i size=%i length=%i " "value=%lld\n", i, params[i].c_type, params[i].type, params[i].buffer_length, params[i].size, params[i].length, *number); } else if (value->IsNumber()) { double *number = new double(value->NumberValue()); params[i].c_type = SQL_C_DOUBLE; params[i].type = SQL_DECIMAL; params[i].buffer = number; params[i].buffer_length = sizeof(double); params[i].length = params[i].buffer_length; params[i].decimals = 7; params[i].size = sizeof(double); DEBUG_PRINTF("ODBC::GetParametersFromArray - IsNumber(): params[%i] " "c_type=%i type=%i buffer_length=%i size=%i length=%i " "value=%f\n", i, params[i].c_type, params[i].type, params[i].buffer_length, params[i].size, params[i].length, *number); } else if (value->IsBoolean()) { bool *boolean = new bool(value->BooleanValue()); params[i].c_type = SQL_C_BIT; params[i].type = SQL_BIT; params[i].buffer = boolean; params[i].length = 0; DEBUG_PRINTF("ODBC::GetParametersFromArray - IsBoolean(): params[%i] " "c_type=%i type=%i buffer_length=%i size=%i length=%i\n", i, params[i].c_type, params[i].type, params[i].buffer_length, params[i].size, params[i].length); } } return params; }
void FieldAccessor::SetJavaField(Isolate *isolate, const Local<Object>& target, const Local<Value>& value, FieldCallbackData *fieldData) { JEnv env; HandleScope handleScope(isolate); auto runtime = Runtime::GetRuntime(isolate); auto objectManager = runtime->GetObjectManager(); JniLocalRef targetJavaObject; const auto& fieldTypeName = fieldData->signature; auto isStatic = fieldData->isStatic; auto isPrimitiveType = fieldTypeName.size() == 1; auto isFieldArray = fieldTypeName[0] == '['; if (fieldData->fid == nullptr) { auto fieldJniSig = isPrimitiveType ? fieldTypeName : (isFieldArray ? fieldTypeName : ("L" + fieldTypeName + ";")); if (isStatic) { fieldData->clazz = env.FindClass(fieldData->declaringType); assert(fieldData->clazz != nullptr); fieldData->fid = env.GetStaticFieldID(fieldData->clazz, fieldData->name, fieldJniSig); assert(fieldData->fid != nullptr); } else { fieldData->clazz = env.FindClass(fieldData->declaringType); assert(fieldData->clazz != nullptr); fieldData->fid = env.GetFieldID(fieldData->clazz, fieldData->name, fieldJniSig); assert(fieldData->fid != nullptr); } } if (!isStatic) { targetJavaObject = objectManager->GetJavaObjectByJsObject(target); if (targetJavaObject.IsNull()) { stringstream ss; ss << "Cannot access property '" << fieldData->name << "' because there is no corresponding Java object"; throw NativeScriptException(ss.str()); } } auto fieldId = fieldData->fid; auto clazz = fieldData->clazz; if (isPrimitiveType) { switch (fieldTypeName[0]) { case 'Z': //bool { //TODO: validate value is a boolean before calling if (isStatic) { env.SetStaticBooleanField(clazz, fieldId, value->BooleanValue()); } else { env.SetBooleanField(targetJavaObject, fieldId, value->BooleanValue()); } break; } case 'B': //byte { //TODO: validate value is a byte before calling if (isStatic) { env.SetStaticByteField(clazz, fieldId, value->Int32Value()); } else { env.SetByteField(targetJavaObject, fieldId, value->Int32Value()); } break; } case 'C': //char { //TODO: validate value is a single char String::Utf8Value stringValue(value->ToString()); JniLocalRef value(env.NewStringUTF(*stringValue)); const char* chars = env.GetStringUTFChars(value, 0); if (isStatic) { env.SetStaticCharField(clazz, fieldId, chars[0]); } else { env.SetCharField(targetJavaObject, fieldId, chars[0]); } env.ReleaseStringUTFChars(value, chars); break; } case 'S': //short { //TODO: validate value is a short before calling if (isStatic) { env.SetStaticShortField(clazz, fieldId, value->Int32Value()); } else { env.SetShortField(targetJavaObject, fieldId, value->Int32Value()); } break; } case 'I': //int { //TODO: validate value is a int before calling if (isStatic) { env.SetStaticIntField(clazz, fieldId, value->Int32Value()); } else { env.SetIntField(targetJavaObject, fieldId, value->Int32Value()); } break; } case 'J': //long { jlong longValue = static_cast<jlong>(ArgConverter::ConvertToJavaLong(value)); if (isStatic) { env.SetStaticLongField(clazz, fieldId, longValue); } else { env.SetLongField(targetJavaObject, fieldId, longValue); } break; } case 'F': //float { if (isStatic) { env.SetStaticFloatField(clazz, fieldId, static_cast<jfloat>(value->NumberValue())); } else { env.SetFloatField(targetJavaObject, fieldId, static_cast<jfloat>(value->NumberValue())); } break; } case 'D': //double { if (isStatic) { env.SetStaticDoubleField(clazz, fieldId, value->NumberValue()); } else { env.SetDoubleField(targetJavaObject, fieldId, value->NumberValue()); } break; } default: { stringstream ss; ss << "(InternalError): in FieldAccessor::SetJavaField: Unknown field type: '" << fieldTypeName[0] << "'"; throw NativeScriptException(ss.str()); } } } else { bool isString = fieldTypeName == "java/lang/String"; JniLocalRef result; if (!value->IsNull()) { if (isString) { //TODO: validate valie is a string; result = ConvertToJavaString(value); } else { auto objectWithHiddenID = value->ToObject(); result = objectManager->GetJavaObjectByJsObject(objectWithHiddenID); } } if (isStatic) { env.SetStaticObjectField(clazz, fieldId, result); } else { env.SetObjectField(targetJavaObject, fieldId, result); } } }
Handle<Value> Query::New(Arguments const& args) { HandleScope scope; if (!args.IsConstructCall()) { return ThrowException(Exception::Error(String::New("Cannot call constructor as function, you need to use 'new' keyword"))); } try { if (args.Length() != 1) { return ThrowException(Exception::TypeError(String::New("please provide an object of options for the first argument"))); } if (!args[0]->IsObject()) { return ThrowException(Exception::TypeError(String::New("first argument must be an object"))); } Local<Object> obj = args[0]->ToObject(); if (obj->IsNull() || obj->IsUndefined()) { return ThrowException(Exception::TypeError(String::New("first arg must be an object"))); } if (!obj->Has(String::New("coordinates"))) { return ThrowException(Exception::TypeError(String::New("must provide a coordinates property"))); } Local<Value> coordinates = obj->Get(String::New("coordinates")); if (!coordinates->IsArray()) { return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs"))); } // Handle scenario in which caller explicitly specified service std::string service; if (obj->Has(String::New("service"))) { Local<Value> serviceValue = obj->Get(String::New("service")); v8::String::Utf8Value serviceUtf8Value(serviceValue->ToString()); service = std::string(*serviceUtf8Value); } // Handle 'nearest', otherwise assume 'viaroute' service. if (service == "nearest" || service == "locate") { Local<Array> coordinates_array = Local<Array>::Cast(coordinates); if (coordinates_array->Length() != 1) { return ThrowException(Exception::TypeError(String::New("coordinates array should only have one lat/long pair for 'nearest' or 'locate' queries"))); } Local<Value> coordinate = coordinates_array->Get(0); if (!coordinate->IsArray()) { return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs"))); } Local<Array> coordinate_array = Local<Array>::Cast(coordinate); if (coordinate_array->Length() != 2) { return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs"))); } Query* q = new Query(); q->this_->service = service; q->this_->coordinates.push_back( FixedPointCoordinate(coordinate_array->Get(0)->NumberValue()*COORDINATE_PRECISION, coordinate_array->Get(1)->NumberValue()*COORDINATE_PRECISION)); q->Wrap(args.This()); return args.This(); } Local<Array> coordinates_array = Local<Array>::Cast(coordinates); if (coordinates_array->Length() < 2) { return ThrowException(Exception::TypeError(String::New("at least two coordinates must be provided"))); } Query* q = new Query(); q->this_->zoomLevel = 18; //no generalization q->this_->printInstructions = false; //turn by turn instructions q->this_->alternateRoute = true; //get an alternate route, too q->this_->geometry = true; //retrieve geometry of route q->this_->compression = true; //polyline encoding q->this_->checkSum = UINT_MAX; //see wiki q->this_->service = "viaroute"; //that's routing q->this_->outputFormat = "json"; q->this_->jsonpParameter = ""; //set for jsonp wrapping q->this_->language = ""; //unused atm if (obj->Has(String::New("alternateRoute"))) { q->this_->alternateRoute = obj->Get(String::New("alternateRoute"))->BooleanValue(); } if (obj->Has(String::New("checksum"))) { q->this_->checkSum = static_cast<unsigned>(obj->Get(String::New("checksum"))->Uint32Value()); } if (obj->Has(String::New("zoomLevel"))) { q->this_->zoomLevel = static_cast<short>(obj->Get(String::New("zoomLevel"))->Int32Value()); } if (obj->Has(String::New("printInstructions"))) { q->this_->printInstructions = obj->Get(String::New("printInstructions"))->BooleanValue(); } if (obj->Has(String::New("jsonpParameter"))) { q->this_->jsonpParameter = *v8::String::Utf8Value(obj->Get(String::New("jsonpParameter"))); } if (obj->Has(String::New("hints"))) { Local<Value> hints = obj->Get(String::New("hints")); if (!hints->IsArray()) { return ThrowException(Exception::TypeError(String::New("hints must be an array of strings/null"))); } Local<Array> hints_array = Local<Array>::Cast(hints); for (uint32_t i = 0; i < hints_array->Length(); ++i) { Local<Value> hint = hints_array->Get(i); if (hint->IsString()) { q->this_->hints.push_back(*v8::String::Utf8Value(hint)); } else if(hint->IsNull()){ q->this_->hints.push_back(""); }else{ return ThrowException(Exception::TypeError(String::New("hint must be null or string"))); } } } for (uint32_t i = 0; i < coordinates_array->Length(); ++i) { Local<Value> coordinate = coordinates_array->Get(i); if (!coordinate->IsArray()) { return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs"))); } Local<Array> coordinate_array = Local<Array>::Cast(coordinate); if (coordinate_array->Length() != 2) { return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs"))); } q->this_->coordinates.push_back( FixedPointCoordinate(coordinate_array->Get(0)->NumberValue()*COORDINATE_PRECISION, coordinate_array->Get(1)->NumberValue()*COORDINATE_PRECISION)); } q->Wrap(args.This()); return args.This(); } catch (std::exception const& ex) { return ThrowException(Exception::TypeError(String::New(ex.what()))); } return Undefined(); }