jstring jstr = env->NewString((const jchar*) str->get(), str->Length());
jstring jstr; jstr = env->NewString((const jchar*) str->get(), str->Length()); if (!jstr) { rv = NS_ERROR_OUT_OF_MEMORY; break; }
FinalizeParams(JNIEnv *env, const jobject aParam,                const nsXPTParamInfo &aParamInfo,                const nsXPTMethodInfo* aMethodInfo,                nsIInterfaceInfo* aIInfo,                PRUint16 aMethodIndex,                nsXPTCVariant* aDispatchParams,                nsXPTCVariant &aVariant){  nsresult rv = NS_OK;  const nsXPTType &type = aParamInfo.GetType();  // Only write the array elements back if the parameter is an output param  jint mode = 0;  if (!aParamInfo.IsOut() && !aParamInfo.IsRetval())    mode = JNI_ABORT;  switch (type.TagPart())  {    case nsXPTType::T_I8:    case nsXPTType::T_U8:    {      if (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD) {        env->ReleaseByteArrayElements((jbyteArray) aParam,                                      (jbyte*) aVariant.val.p, mode);      }    }    break;    case nsXPTType::T_I16:    case nsXPTType::T_U16:    {      if (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD) {        env->ReleaseShortArrayElements((jshortArray) aParam,                                       (jshort*) aVariant.val.p, mode);      }    }    break;    case nsXPTType::T_I32:    case nsXPTType::T_U32:    {      if (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD) {        env->ReleaseIntArrayElements((jintArray) aParam,                                     (jint*) aVariant.val.p, mode);      }    }    break;    case nsXPTType::T_I64:    case nsXPTType::T_U64:    {      if (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD) {        env->ReleaseLongArrayElements((jlongArray) aParam,                                      (jlong*) aVariant.val.p, mode);      }    }    break;    case nsXPTType::T_FLOAT:    {      if (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD) {        env->ReleaseFloatArrayElements((jfloatArray) aParam,                                       (jfloat*) aVariant.val.p, mode);      }    }    break;    case nsXPTType::T_DOUBLE:    {      if (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD) {        env->ReleaseDoubleArrayElements((jdoubleArray) aParam,                                        (jdouble*) aVariant.val.p, mode);      }    }    break;    case nsXPTType::T_BOOL:    {      if (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD) {        env->ReleaseBooleanArrayElements((jbooleanArray) aParam,                                         (jboolean*) aVariant.val.p, mode);      }    }    break;    case nsXPTType::T_CHAR:    case nsXPTType::T_WCHAR:    {      if (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD) {        env->ReleaseCharArrayElements((jcharArray) aParam,                                      (jchar*) aVariant.val.p, mode);      }    }    break;    case nsXPTType::T_CHAR_STR:    {      // release Java string buffer      if (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD) {        jstring data = nsnull;        if (!aParamInfo.IsOut()) {          data = (jstring) aParam;        } else {          data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam, 0);        }        env->ReleaseStringUTFChars(data, (const char*) aVariant.val.p);      }      // If this is an output parameter, then create the string to return      if (aParam && aParamInfo.IsOut()) {        jstring str = env->NewStringUTF((const char*) aVariant.val.p);        env->SetObjectArrayElement((jobjectArray) aParam, 0, str);      }    }    break;    case nsXPTType::T_WCHAR_STR:    {      // release Java string buffer      if (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD) {        jstring data = nsnull;        if (!aParamInfo.IsOut()) {          data = (jstring) aParam;        } else {          data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam, 0);        }        env->ReleaseStringChars(data, (const jchar*) aVariant.val.p);      }      // If this is an output parameter, then create the string to return      if (aParam && aParamInfo.IsOut()) {        PRUint32 length = nsCRT::strlen((const PRUnichar*) aVariant.val.p);        jstring str = env->NewString((const jchar*) aVariant.val.p, length);        env->SetObjectArrayElement((jobjectArray) aParam, 0, str);      }    }    break;    case nsXPTType::T_IID:    {      nsID* iid = (nsID*) aVariant.val.p;      // If this is an output parameter, then create the string to return      if (iid && aParamInfo.IsOut()) {        char* iid_str = iid->ToString();        jstring str = env->NewStringUTF(iid_str);        PR_Free(iid_str);        env->SetObjectArrayElement((jobjectArray) aParam, 0, str);      }      // Ordinarily, we would delete 'iid' here.  But we cannot do that until      // we've handled all of the params.  See comment in CallXPCOMMethod    }    break;    case nsXPTType::T_INTERFACE:    case nsXPTType::T_INTERFACE_IS:    {      if (aVariant.val.p && aParamInfo.IsOut()) {        jobject java_obj = GetMatchingJavaObject(env, aVariant.val.p);        if (java_obj == nsnull) {          // wrap xpcom instance          nsID iid;          JavaXPCOMInstance* inst;          rv = GetIIDForMethodParam(aIInfo, aMethodInfo, aParamInfo,                                    aMethodIndex, aDispatchParams, PR_TRUE, iid);          if (NS_FAILED(rv))            return rv;          nsISupports* variant =                              NS_REINTERPRET_CAST(nsISupports*, aVariant.val.p);          inst = CreateJavaXPCOMInstance(variant, &iid);          NS_RELEASE(variant);   // JavaXPCOMInstance has owning ref          if (inst) {            // create java stub            char* iface_name;            inst->InterfaceInfo()->GetName(&iface_name);            java_obj = CreateJavaWrapper(env, iface_name);            if (java_obj) {              // Associate XPCOM object w/ Java stub              AddJavaXPCOMBinding(env, java_obj, inst);            }          }        }        env->SetObjectArrayElement((jobjectArray) aParam, 0, java_obj);      }      // If VAL_IS_ALLOCD is set, that means that an XPCOM object was created      // is SetupParams that now needs to be released.      if (aVariant.val.p &&          (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD)) {        nsISupports* variant = NS_STATIC_CAST(nsISupports*, aVariant.val.p);        NS_RELEASE(variant);      }    }    break;    case nsXPTType::T_ASTRING:    case nsXPTType::T_DOMSTRING:    {      nsString* str = (nsString*) aVariant.val.p;      if (str) {        if (aParamInfo.IsOut()) {          jstring jstr = env->NewString((const jchar*) str->get(), str->Length());          env->SetObjectArrayElement((jobjectArray) aParam, 0, jstr);        }        delete str;      }    }    break;    case nsXPTType::T_UTF8STRING:    case nsXPTType::T_CSTRING:    {      nsCString* str = (nsCString*) aVariant.val.p;      if (str) {        if (aParamInfo.IsOut()) {          jstring jstr = env->NewStringUTF((const char*) str->get());          env->SetObjectArrayElement((jobjectArray) aParam, 0, jstr);        }        delete str;      }    }    break;    case nsXPTType::T_VOID:    {      if (aVariant.flags & nsXPTCVariant::VAL_IS_ALLOCD) {        env->ReleaseIntArrayElements((jintArray) aParam,                                     (jint*) aVariant.val.p, mode);      }    }    break;  }  return rv;}