bool JavaNPObject_GetProperty(NPObject* obj, NPIdentifier identifier, NPVariant* result) { VOID_TO_NPVARIANT(*result); JavaInstance* instance = ExtractJavaInstance(obj); if (instance == 0) return false; NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); if (name == 0) return false; JavaField* field = instance->getClass()->fieldNamed(name); free(name); // TODO: use NPN_MemFree if (field == 0) { return false; } jobject local_ref = instance->getLocalRef(); jvalue value = getJNIField(local_ref, field->getJNIType(), field->name(), field->type()); getJNIEnv()->DeleteLocalRef(local_ref); convertJValueToNPVariant(value, field->getJNIType(), field->type(), result); return true; }
bool JavaNPObjectGetProperty(NPObject* obj, NPIdentifier identifier, NPVariant* result) { VOID_TO_NPVARIANT(*result); JavaInstance* instance = ExtractJavaInstance(obj); if (!instance) return false; NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); if (!name) return false; instance->begin(); JavaField* field = instance->getClass()->fieldNamed(name); free(name); // TODO: use NPN_MemFree if (!field) { instance->end(); return false; } #if PLATFORM(ANDROID) // JSC does not seem to support returning object properties so we emulate that // behaviour here. JavaValue value; #else JavaValue value = instance->getField(field); #endif // PLATFORM(ANDROID) instance->end(); convertJavaValueToNPVariant(value, result); return true; }
bool JavaNPObject_HasProperty(NPObject* obj, NPIdentifier identifier) { JavaInstance* instance = ExtractJavaInstance(obj); if (instance == 0) return false; NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); if (name == 0) return false; bool result = instance->getClass()->fieldNamed(name) != 0; free(name); return result; }
bool JavaNPObject_HasMethod(NPObject* obj, NPIdentifier identifier) { JavaInstance* instance = ExtractJavaInstance(obj); if (instance == 0) return false; NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); if (name == 0) return false; bool result = (instance->getClass()->methodsNamed(name).size() > 0); // TODO: use NPN_MemFree free(name); return result; }
bool JavaNPObject_Invoke(NPObject* obj, NPIdentifier identifier, const NPVariant* args, uint32_t argCount, NPVariant* result) { JavaInstance* instance = ExtractJavaInstance(obj); if (instance == 0) return false; NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); if (name == 0) return false; bool r = instance->invokeMethod(name, args, argCount, result); // TODO: use NPN_MemFree free(name); return r; }
bool JavaNPObjectInvoke(NPObject* obj, NPIdentifier identifier, const NPVariant* args, uint32_t argCount, NPVariant* result) { JavaInstance* instance = ExtractJavaInstance(obj); if (!instance) return false; NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); if (!name) return false; instance->begin(); MethodList methodList = instance->getClass()->methodsNamed(name); // TODO: use NPN_MemFree free(name); // Try to find a good match for the overloaded method. The // fundamental problem is that JavaScript doesn't have the // notion of method overloading and Java does. We could // get a bit more sophisticated and attempt to do some // type checking as well as checking the number of parameters. size_t numMethods = methodList.size(); JavaMethod* aMethod; JavaMethod* jMethod = 0; for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) { aMethod = methodList[methodIndex]; if (aMethod->numParameters() == static_cast<int>(argCount)) { jMethod = aMethod; break; } } if (!jMethod) { instance->end(); return false; } JavaValue* jArgs = new JavaValue[argCount]; for (unsigned int i = 0; i < argCount; i++) jArgs[i] = convertNPVariantToJavaValue(args[i], jMethod->parameterAt(i)); JavaValue jResult = instance->invokeMethod(jMethod, jArgs); instance->end(); delete[] jArgs; VOID_TO_NPVARIANT(*result); convertJavaValueToNPVariant(jResult, result); return true; }
bool JavaNPObjectGetProperty(NPObject* obj, NPIdentifier identifier, NPVariant* result) { VOID_TO_NPVARIANT(*result); JavaInstance* instance = ExtractJavaInstance(obj); if (!instance) return false; NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); if (!name) return false; instance->begin(); JavaField* field = instance->getClass()->fieldNamed(name); free(name); // TODO: use NPN_MemFree if (!field) return false; JavaValue value = instance->getField(field); instance->end(); convertJavaValueToNPVariant(value, result); return true; }
JavaValue convertNPVariantToJavaValue(NPVariant value, const String& javaClass) { CString javaClassName = javaClass.utf8(); JavaType javaType = javaTypeFromClassName(javaClassName.data()); JavaValue result; result.m_type = javaType; NPVariantType type = value.type; switch (javaType) { case JavaTypeArray: case JavaTypeObject: { // See if we have a Java instance. if (type == NPVariantType_Object) { NPObject* objectImp = NPVARIANT_TO_OBJECT(value); result.m_objectValue = ExtractJavaInstance(objectImp); } } break; case JavaTypeString: { #ifdef CONVERT_NULL_TO_EMPTY_STRING if (type == NPVariantType_Null) { result.m_type = JavaTypeString; result.m_stringValue = String::fromUTF8(""); } else #else if (type == NPVariantType_String) #endif { NPString src = NPVARIANT_TO_STRING(value); result.m_type = JavaTypeString; result.m_stringValue = String::fromUTF8(src.UTF8Characters); } } break; case JavaTypeBoolean: { if (type == NPVariantType_Bool) result.m_booleanValue = NPVARIANT_TO_BOOLEAN(value); } break; case JavaTypeByte: { if (type == NPVariantType_Int32) result.m_byteValue = static_cast<signed char>(NPVARIANT_TO_INT32(value)); else if (type == NPVariantType_Double) result.m_byteValue = static_cast<signed char>(NPVARIANT_TO_DOUBLE(value)); } break; case JavaTypeChar: { if (type == NPVariantType_Int32) result.m_charValue = static_cast<unsigned short>(NPVARIANT_TO_INT32(value)); } break; case JavaTypeShort: { if (type == NPVariantType_Int32) result.m_shortValue = static_cast<short>(NPVARIANT_TO_INT32(value)); else if (type == NPVariantType_Double) result.m_shortValue = static_cast<short>(NPVARIANT_TO_DOUBLE(value)); } break; case JavaTypeInt: { if (type == NPVariantType_Int32) result.m_intValue = static_cast<int>(NPVARIANT_TO_INT32(value)); else if (type == NPVariantType_Double) result.m_intValue = static_cast<int>(NPVARIANT_TO_DOUBLE(value)); } break; case JavaTypeLong: { if (type == NPVariantType_Int32) result.m_longValue = static_cast<long long>(NPVARIANT_TO_INT32(value)); else if (type == NPVariantType_Double) result.m_longValue = static_cast<long long>(NPVARIANT_TO_DOUBLE(value)); } break; case JavaTypeFloat: { if (type == NPVariantType_Int32) result.m_floatValue = static_cast<float>(NPVARIANT_TO_INT32(value)); else if (type == NPVariantType_Double) result.m_floatValue = static_cast<float>(NPVARIANT_TO_DOUBLE(value)); } break; case JavaTypeDouble: { if (type == NPVariantType_Int32) result.m_doubleValue = static_cast<double>(NPVARIANT_TO_INT32(value)); else if (type == NPVariantType_Double) result.m_doubleValue = static_cast<double>(NPVARIANT_TO_DOUBLE(value)); } break; default: break; } return result; }
jvalue convertNPVariantToJValue(NPVariant value, JNIType jniType, const char* javaClassName) { jvalue result; NPVariantType type = value.type; switch (jniType) { case array_type: case object_type: { result.l = static_cast<jobject>(0); // First see if we have a Java instance. if (type == NPVariantType_Object) { NPObject* objectImp = NPVARIANT_TO_OBJECT(value); if (JavaInstance* instance = ExtractJavaInstance(objectImp)) result.l = instance->javaInstance(); } // Now convert value to a string if the target type is a java.lang.string, and we're not // converting from a Null. if (!result.l && !strcmp(javaClassName, "java.lang.String")) { #ifdef CONVERT_NULL_TO_EMPTY_STRING if (type == NPVariantType_Null) { JNIEnv* env = getJNIEnv(); jchar buf[2]; jobject javaString = env->functions->NewString(env, buf, 0); result.l = javaString; } else #else if (type == NPVariantType_String) #endif { NPString src = NPVARIANT_TO_STRING(value); JNIEnv* env = getJNIEnv(); jobject javaString = env->NewStringUTF(src.UTF8Characters); result.l = javaString; } } else if (!result.l) memset(&result, 0, sizeof(jvalue)); // Handle it the same as a void case } break; case boolean_type: { if (type == NPVariantType_Bool) result.z = NPVARIANT_TO_BOOLEAN(value); else memset(&result, 0, sizeof(jvalue)); // as void case } break; case byte_type: { if (type == NPVariantType_Int32) result.b = static_cast<char>(NPVARIANT_TO_INT32(value)); else memset(&result, 0, sizeof(jvalue)); } break; case char_type: { if (type == NPVariantType_Int32) result.c = static_cast<char>(NPVARIANT_TO_INT32(value)); else memset(&result, 0, sizeof(jvalue)); } break; case short_type: { if (type == NPVariantType_Int32) result.s = static_cast<jshort>(NPVARIANT_TO_INT32(value)); else memset(&result, 0, sizeof(jvalue)); } break; case int_type: { if (type == NPVariantType_Int32) result.i = static_cast<jint>(NPVARIANT_TO_INT32(value)); else memset(&result, 0, sizeof(jvalue)); } break; case long_type: { if (type == NPVariantType_Int32) result.j = static_cast<jlong>(NPVARIANT_TO_INT32(value)); else if (type == NPVariantType_Double) result.j = static_cast<jlong>(NPVARIANT_TO_DOUBLE(value)); else memset(&result, 0, sizeof(jvalue)); } break; case float_type: { if (type == NPVariantType_Int32) result.f = static_cast<jfloat>(NPVARIANT_TO_INT32(value)); else if (type == NPVariantType_Double) result.f = static_cast<jfloat>(NPVARIANT_TO_DOUBLE(value)); else memset(&result, 0, sizeof(jvalue)); } break; case double_type: { if (type == NPVariantType_Int32) result.d = static_cast<jdouble>(NPVARIANT_TO_INT32(value)); else if (type == NPVariantType_Double) result.d = static_cast<jdouble>(NPVARIANT_TO_DOUBLE(value)); else memset(&result, 0, sizeof(jvalue)); } break; break; case invalid_type: default: case void_type: { memset(&result, 0, sizeof(jvalue)); } break; } return result; }