// @method string|Py_nsISupports|__repr__|Called to create a representation of a Py_nsISupports object
/*static */PyObject *
PyXPCOM_TypeObject::Py_repr(PyObject *self)
{
	// @comm The repr of this object displays both the object's address, and its attached nsISupports's address
	Py_nsISupports *pis = (Py_nsISupports *)self;
	// Try and get the IID name.
	char *iid_repr = nsnull;
	nsCOMPtr<nsIInterfaceInfoManager> iim(do_GetService(
	                NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
	if (iim!=nsnull)
		iim->GetNameForIID(&pis->m_iid, &iid_repr);
	if (iid_repr==nsnull)
		// no IIM available, or it doesnt know the name.
		iid_repr = pis->m_iid.ToString();
	// XXX - need some sort of buffer overflow.
	char buf[512];
#ifdef VBOX
	snprintf(buf, sizeof(buf), "<XPCOM object (%s) at %p/%p>",
	        iid_repr, (void *)self, (void *)pis->m_obj.get());
#else
	sprintf(buf, "<XPCOM object (%s) at 0x%p/0x%p>",
	        iid_repr, (void *)self, (void *)pis->m_obj.get());
#endif
	nsMemory::Free(iid_repr);
#if PY_MAJOR_VERSION <= 2
	return PyString_FromString(buf);
#else
	return PyUnicode_FromString(buf);
#endif
}
static const void *
find (const void *(*match) (nsIInterfaceInfo *, void *), void *item)
{
  nsCOMPtr <nsIInterfaceInfoManager> iim (do_GetService (NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
  nsIEnumerator *Interfaces = nsnull;
  nsISupports *is_Interface;
  nsIInterfaceInfo *Interface;
  nsresult rv;
  const void *ret = NULL;
  
  if (NS_FAILED (iim->EnumerateInterfaces (&Interfaces)))
    {
      NS_ASSERTION (0, "failed to get interface enumeration");
      goto done;
    }
  
  if (NS_FAILED (rv = Interfaces->First ()))
    {
      NS_ASSERTION (0, "failed to go to first item in interface enumeration");
      goto done;
    }
  
  do
    {
      if (NS_FAILED (rv = Interfaces->CurrentItem (&is_Interface))) {
          /* maybe something should be done,
           * debugging info at least? */
          Interfaces->Next ();
          continue;
        }
      
      rv = is_Interface->
        QueryInterface (NS_GET_IID (nsIInterfaceInfo),
                        (void **) &Interface);
      
      if (!NS_FAILED (rv))
	ret = (*match) (Interface, item);
      else
        abort ();
      
      if (ret)
        break;

      NS_RELEASE (Interface);
      NS_RELEASE (is_Interface);
      Interfaces->Next ();
      
    } while (Interfaces->IsDone () == NS_ENUMERATOR_FALSE);
  
 done:
  NS_IF_RELEASE (Interfaces);
  NS_IF_RELEASE (iim);
  NS_IF_RELEASE (is_Interface);
  
  return ret;
}
nsresult
nsScriptNameSpaceManager::FillHashWithDOMInterfaces()
{
  nsCOMPtr<nsIInterfaceInfoManager>
    iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
  NS_ENSURE_TRUE(iim, NS_ERROR_UNEXPECTED);

  // First look for all interfaces whose name starts with nsIDOM
  nsCOMPtr<nsIEnumerator> domInterfaces;
  nsresult rv =
    iim->EnumerateInterfacesWhoseNamesStartWith(NS_DOM_INTERFACE_PREFIX,
                                                getter_AddRefs(domInterfaces));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsISupports> entry;

  rv = domInterfaces->First();

  if (NS_FAILED(rv)) {
    // Empty interface list?

    NS_WARNING("What, no nsIDOM interfaces installed?");

    return NS_OK;
  }

  bool found_old;
  nsCOMPtr<nsIInterfaceInfo> if_info;
  const char *if_name = nsnull;
  const nsIID *iid;

  for ( ; domInterfaces->IsDone() == NS_ENUMERATOR_FALSE; domInterfaces->Next()) {
    rv = domInterfaces->CurrentItem(getter_AddRefs(entry));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIInterfaceInfo> if_info(do_QueryInterface(entry));
    if_info->GetNameShared(&if_name);
    if_info->GetIIDShared(&iid);
    rv = RegisterInterface(if_name + sizeof(NS_DOM_INTERFACE_PREFIX) - 1,
                           iid, &found_old);

#ifdef DEBUG
    NS_ASSERTION(!found_old,
                 "Whaaa, interface name already in hash!");
#endif
  }

  // Next, look for externally registered DOM interfaces
  rv = RegisterExternalInterfaces(false);

  return rv;
}
Beispiel #4
0
/*static*/ nsresult
nsJavaXPTCStub::GetNewOrUsed(JNIEnv* env, jobject aJavaObject,
                             const nsIID& aIID, void** aResult)
{
  nsJavaXPTCStub* stub;
  jint hash = env->CallStaticIntMethod(systemClass, hashCodeMID, aJavaObject);
  nsresult rv = gJavaToXPTCStubMap->Find(hash, aIID, &stub);
  NS_ENSURE_SUCCESS(rv, rv);
  if (stub) {
    // stub is already AddRef'd and QI'd
    *aResult = stub;
    return NS_OK;
  }

  // If there is no corresponding XPCOM object, then that means that the
  // parameter is a non-generated class (that is, it is not one of our
  // Java stubs that represent an exising XPCOM object).  So we need to
  // create an XPCOM stub, that can route any method calls to the class.

  // Get interface info for class
  nsCOMPtr<nsIInterfaceInfoManager>
    iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIInterfaceInfo> iinfo;
  rv = iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo));
  NS_ENSURE_SUCCESS(rv, rv);

  // Create XPCOM stub
  stub = new nsJavaXPTCStub(aJavaObject, iinfo, &rv);
  if (!stub)
    return NS_ERROR_OUT_OF_MEMORY;
  if (NS_FAILED(rv)) {
    delete stub;
    return rv;
  }

  rv = gJavaToXPTCStubMap->Add(hash, stub);
  if (NS_FAILED(rv)) {
    delete stub;
    return rv;
  }

  NS_ADDREF(stub);
  *aResult = stub;

  return NS_OK;
}
Beispiel #5
0
/*static*/PyObject *
Py_nsIID::PyTypeMethod_getattr(PyObject *self, char *name)
{
	Py_nsIID *me = (Py_nsIID *)self;
	if (strcmp(name, "name")==0) {
		char *iid_repr = nsnull;
		nsCOMPtr<nsIInterfaceInfoManager> iim(do_GetService(
		                NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
		if (iim!=nsnull)
			iim->GetNameForIID(&me->m_iid, &iid_repr);
		if (iid_repr==nsnull)
			iid_repr = me->m_iid.ToString();
		PyObject *ret;
		if (iid_repr != nsnull) {
			ret = PyString_FromString(iid_repr);
			nsMemory::Free(iid_repr);
		} else
			ret = PyString_FromString("<cant get IID info!>");
		return ret;
	}
	return PyErr_Format(PyExc_AttributeError, "IID objects have no attribute '%s'", name);
}
nsresult
nsScriptNameSpaceManager::RegisterExternalInterfaces(bool aAsProto)
{
  nsresult rv;
  nsCOMPtr<nsICategoryManager> cm =
    do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIInterfaceInfoManager>
    iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
  NS_ENSURE_TRUE(iim, NS_ERROR_NOT_AVAILABLE);

  nsCOMPtr<nsISimpleEnumerator> enumerator;
  rv = cm->EnumerateCategory(JAVASCRIPT_DOM_INTERFACE,
                             getter_AddRefs(enumerator));
  NS_ENSURE_SUCCESS(rv, rv);

  nsXPIDLCString IID_string;
  nsCAutoString category_entry;
  const char* if_name;
  nsCOMPtr<nsISupports> entry;
  nsCOMPtr<nsIInterfaceInfo> if_info;
  bool found_old, dom_prefix;

  while (NS_SUCCEEDED(enumerator->GetNext(getter_AddRefs(entry)))) {
    nsCOMPtr<nsISupportsCString> category(do_QueryInterface(entry));

    if (!category) {
      NS_WARNING("Category entry not an nsISupportsCString!");

      continue;
    }

    rv = category->GetData(category_entry);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = cm->GetCategoryEntry(JAVASCRIPT_DOM_INTERFACE, category_entry.get(),
                              getter_Copies(IID_string));
    NS_ENSURE_SUCCESS(rv, rv);

    nsIID primary_IID;
    if (!primary_IID.Parse(IID_string) ||
        primary_IID.Equals(NS_GET_IID(nsISupports))) {
      NS_ERROR("Invalid IID registered with the script namespace manager!");
      continue;
    }

    iim->GetInfoForIID(&primary_IID, getter_AddRefs(if_info));

    while (if_info) {
      const nsIID *iid;
      if_info->GetIIDShared(&iid);
      NS_ENSURE_TRUE(iid, NS_ERROR_UNEXPECTED);

      if (iid->Equals(NS_GET_IID(nsISupports))) {
        break;
      }

      if_info->GetNameShared(&if_name);
      dom_prefix = (strncmp(if_name, NS_DOM_INTERFACE_PREFIX,
                            sizeof(NS_DOM_INTERFACE_PREFIX) - 1) == 0);

      const char* name;
      if (dom_prefix) {
        if (!aAsProto) {
          // nsIDOM* interfaces have already been registered.
          break;
        }
        name = if_name + sizeof(NS_DOM_INTERFACE_PREFIX) - 1;
      } else {
        name = if_name + sizeof(NS_INTERFACE_PREFIX) - 1;
      }

      if (aAsProto) {
        RegisterClassProto(name, iid, &found_old);
      } else {
        RegisterInterface(name, iid, &found_old);
      }

      if (found_old) {
        break;
      }

      nsCOMPtr<nsIInterfaceInfo> tmp(if_info);
      tmp->GetParent(getter_AddRefs(if_info));
    }
  }

  return NS_OK;
}
int main (int argc, char **argv) {
    int i;
    nsIID *iid1, *iid2, *iid3;
    char *name1, *name2, *name3;
    nsIInterfaceInfo *info2, *info3, *info4, *info5;

    nsCOMPtr<nsIInterfaceInfoManager> iim
        (do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));

    fprintf(stderr, "\ngetting iid for 'nsISupports'\n");
    iim->GetIIDForName("nsISupports", &iid1);
    iim->GetNameForIID(iid1, &name1);
    fprintf(stderr, "%s iid %s\n", name1, iid1->ToString());

    fprintf(stderr, "\ngetting iid for 'nsIInputStream'\n");
    iim->GetIIDForName("nsIInputStream", &iid2);
    iim->GetNameForIID(iid2, &name2);
    fprintf(stderr, "%s iid %s\n", name2, iid2->ToString());

    fprintf(stderr, "iid: %s, name: %s\n", iid1->ToString(), name1);
    fprintf(stderr, "iid: %s, name: %s\n", iid2->ToString(), name2);

    fprintf(stderr, "\ngetting info for iid2 from above\n");
    iim->GetInfoForIID(iid2, &info2);
#ifdef DEBUG
//    ((nsInterfaceInfo *)info2)->print(stderr);
#endif

    fprintf(stderr, "\ngetting iid for 'nsIInputStream'\n");
    iim->GetIIDForName("nsIInputStream", &iid3);
    iim->GetNameForIID(iid3, &name3);
    fprintf(stderr, "%s iid %s\n", name3, iid2->ToString());
    iim->GetInfoForIID(iid3, &info3);
#ifdef DEBUG
//    ((nsInterfaceInfo *)info3)->print(stderr);
#endif

    fprintf(stderr, "\ngetting info for name 'nsIBidirectionalEnumerator'\n");
    iim->GetInfoForName("nsIBidirectionalEnumerator", &info4);
#ifdef DEBUG
//    ((nsInterfaceInfo *)info4)->print(stderr);
#endif

    fprintf(stderr, "\nparams work?\n");
    fprintf(stderr, "\ngetting info for name 'nsIServiceManager'\n");
    iim->GetInfoForName("nsIComponentManager", &info5);
#ifdef DEBUG
//    ((nsInterfaceInfo *)info5)->print(stderr);
#endif

    // XXX: nsIServiceManager is no more; what do we test with?
    if (info5 == NULL) {
        fprintf(stderr, "\nNo nsIComponentManager; cannot continue.\n");
        return 1;
    }

    uint16 methodcount;
    info5->GetMethodCount(&methodcount);
    const nsXPTMethodInfo *mi;
    for (i = 0; i < methodcount; i++) {
        info5->GetMethodInfo(i, &mi);
        fprintf(stderr, "method %d, name %s\n", i, mi->GetName());
    }

    // 4 is getServiceByContractID, which has juicy params.
    info5->GetMethodInfo(6, &mi);

    const nsXPTParamInfo& param2 = mi->GetParam(1);
    // should be IID for the service
    nsIID *nsISL;
    info5->GetIIDForParam(6, &param2, &nsISL);
    fprintf(stderr, "iid assoc'd with param 1 of method 6 - createInstanceByContractID - %s\n", nsISL->ToString());
    // if we look up the name?
    char *nsISLname;
    iim->GetNameForIID(nsISL, &nsISLname);
    fprintf(stderr, "which is called %s\n", nsISLname);

    fprintf(stderr, "\nNow check the last param\n");
    const nsXPTParamInfo& param3 = mi->GetParam(3);

    if (param3.GetType().TagPart() != nsXPTType::T_INTERFACE_IS) {
        fprintf(stderr, "Param 3 is not type interface is\n");
        // Not returning an error, because this could legitamately change
    }
    // lets see what arg this refers to
    uint8 argnum;
    info5->GetInterfaceIsArgNumberForParam(6, &param3, &argnum);
    fprintf(stderr, "param 3 referrs to param %d of method 6 - createInstanceByContractID\n", (uint32_t)argnum);
    // Get the type of the parameter referred to
    const nsXPTParamInfo& arg_param = mi->GetParam(argnum);
    const nsXPTType& arg_type = arg_param.GetType();
    // Check to make sure it refers to the proper param
    if(!arg_type.IsPointer() || arg_type.TagPart() != nsXPTType::T_IID) {
        fprintf(stderr, "Param 3 of method 6 refers to a non IID parameter\n"); 
        // Not returning an error, because this could legitamately change
    }


    return 0;
}    
Beispiel #8
0
/**
 * Handle 'in', 'inout', and 'out' params
 */
nsresult
nsJavaXPTCStub::SetupJavaParams(const nsXPTParamInfo &aParamInfo,
                const XPTMethodDescriptor* aMethodInfo,
                PRUint16 aMethodIndex,
                nsXPTCMiniVariant* aDispatchParams,
                nsXPTCMiniVariant &aVariant, jvalue &aJValue,
                nsACString &aMethodSig)
{
  nsresult rv = NS_OK;
  JNIEnv* env = GetJNIEnv();
  const nsXPTType &type = aParamInfo.GetType();

  PRUint8 tag = type.TagPart();
  switch (tag)
  {
    case nsXPTType::T_I8:
    {
      if (!aParamInfo.IsOut()) {  // 'in'
        aJValue.b = aVariant.val.i8;
        aMethodSig.Append('B');
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          jbyteArray array = env->NewByteArray(1);
          if (!array) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }

          env->SetByteArrayRegion(array, 0, 1, (jbyte*) aVariant.val.p);
          aJValue.l = array;
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.AppendLiteral("[B");
      }
    }
    break;

    case nsXPTType::T_I16:
    case nsXPTType::T_U8:
    {
      if (!aParamInfo.IsOut()) {  // 'in'
        aJValue.s = (tag == nsXPTType::T_I16) ? aVariant.val.i16 :
                                                aVariant.val.u8;
        aMethodSig.Append('S');
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          jshortArray array = env->NewShortArray(1);
          if (!array) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }

          env->SetShortArrayRegion(array, 0, 1, (jshort*) aVariant.val.p);
          aJValue.l = array;
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.AppendLiteral("[S");
      }
    }
    break;

    case nsXPTType::T_I32:
    case nsXPTType::T_U16:
    {
      if (!aParamInfo.IsOut()) {  // 'in'
        aJValue.i = (tag == nsXPTType::T_I32) ? aVariant.val.i32 :
                                                aVariant.val.u16;
        aMethodSig.Append('I');
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          jintArray array = env->NewIntArray(1);
          if (!array) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }

          env->SetIntArrayRegion(array, 0, 1, (jint*) aVariant.val.p);
          aJValue.l = array;
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.AppendLiteral("[I");
      }
    }
    break;

    case nsXPTType::T_I64:
    case nsXPTType::T_U32:
    {
      if (!aParamInfo.IsOut()) {  // 'in'
        aJValue.j = (tag == nsXPTType::T_I64) ? aVariant.val.i64 :
                                                aVariant.val.u32;
        aMethodSig.Append('J');
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          jlongArray array = env->NewLongArray(1);
          if (!array) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }

          env->SetLongArrayRegion(array, 0, 1, (jlong*) aVariant.val.p);
          aJValue.l = array;
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.AppendLiteral("[J");
      }
    }
    break;

    case nsXPTType::T_FLOAT:
    {
      if (!aParamInfo.IsOut()) {  // 'in'
        aJValue.f = aVariant.val.f;
        aMethodSig.Append('F');
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          jfloatArray array = env->NewFloatArray(1);
          if (!array) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }

          env->SetFloatArrayRegion(array, 0, 1, (jfloat*) aVariant.val.p);
          aJValue.l = array;
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.AppendLiteral("[F");
      }
    }
    break;

    // XXX how do we handle unsigned 64-bit values?
    case nsXPTType::T_U64:
    case nsXPTType::T_DOUBLE:
    {
      if (!aParamInfo.IsOut()) {  // 'in'
        aJValue.d = (tag == nsXPTType::T_DOUBLE) ? aVariant.val.d :
                                                   aVariant.val.u64;
        aMethodSig.Append('D');
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          jdoubleArray array = env->NewDoubleArray(1);
          if (!array) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }

          env->SetDoubleArrayRegion(array, 0, 1, (jdouble*) aVariant.val.p);
          aJValue.l = array;
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.AppendLiteral("[D");
      }
    }
    break;

    case nsXPTType::T_BOOL:
    {
      if (!aParamInfo.IsOut()) {  // 'in'
        aJValue.z = aVariant.val.b;
        aMethodSig.Append('Z');
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          jbooleanArray array = env->NewBooleanArray(1);
          if (!array) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }

          env->SetBooleanArrayRegion(array, 0, 1, (jboolean*) aVariant.val.p);
          aJValue.l = array;
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.AppendLiteral("[Z");
      }
    }
    break;

    case nsXPTType::T_CHAR:
    case nsXPTType::T_WCHAR:
    {
      if (!aParamInfo.IsOut()) {  // 'in'
        if (tag == nsXPTType::T_CHAR)
          aJValue.c = aVariant.val.c;
        else
          aJValue.c = aVariant.val.wc;
        aMethodSig.Append('C');
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          jcharArray array = env->NewCharArray(1);
          if (!array) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }

          env->SetCharArrayRegion(array, 0, 1, (jchar*) aVariant.val.p);
          aJValue.l = array;
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.AppendLiteral("[C");
      }
    }
    break;

    case nsXPTType::T_CHAR_STR:
    case nsXPTType::T_WCHAR_STR:
    {
      void* ptr = nsnull;
      if (!aParamInfo.IsOut()) {  // 'in'
        ptr = aVariant.val.p;
      } else if (aVariant.val.p) {  // 'inout' & 'out'
        void** variant = static_cast<void**>(aVariant.val.p);
        ptr = *variant;
      }

      jobject str;
      if (ptr) {
        if (tag == nsXPTType::T_CHAR_STR) {
          str = env->NewStringUTF((const char*) ptr);
        } else {
          const PRUnichar* buf = (const PRUnichar*) ptr;
          str = env->NewString(buf, nsCRT::strlen(buf));
        }
        if (!str) {
          rv = NS_ERROR_OUT_OF_MEMORY;
          break;
        }
      } else {
        str = nsnull;
      }

      if (!aParamInfo.IsOut()) {  // 'in'
        aJValue.l = str;
        aMethodSig.AppendLiteral("Ljava/lang/String;");
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          aJValue.l = env->NewObjectArray(1, stringClass, str);
          if (aJValue.l == nsnull) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.AppendLiteral("[Ljava/lang/String;");
      }
    }
    break;

    case nsXPTType::T_IID:
    {
      nsID* iid = nsnull;
      if (!aParamInfo.IsOut()) {  // 'in'
        iid = static_cast<nsID*>(aVariant.val.p);
      } else if (aVariant.val.p) {  // 'inout' & 'out'
        nsID** variant = static_cast<nsID**>(aVariant.val.p);
        iid = *variant;
      }

      jobject str = nsnull;
      if (iid) {
        char iid_str[NSID_LENGTH];
        iid->ToProvidedString(iid_str);
        str = env->NewStringUTF(iid_str);
        if (!str) {
          rv = NS_ERROR_OUT_OF_MEMORY;
          break;
        }
      }

      if (!aParamInfo.IsOut()) {  // 'in'
        aJValue.l = str;
        aMethodSig.AppendLiteral("Ljava/lang/String;");
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          aJValue.l = env->NewObjectArray(1, stringClass, str);
          if (aJValue.l == nsnull) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.AppendLiteral("[Ljava/lang/String;");
      }
    }
    break;

    case nsXPTType::T_INTERFACE:
    case nsXPTType::T_INTERFACE_IS:
    {
      nsISupports* xpcom_obj = nsnull;
      if (!aParamInfo.IsOut()) {  // 'in'
        xpcom_obj = static_cast<nsISupports*>(aVariant.val.p);
      } else if (aVariant.val.p) {  // 'inout' & 'out'
        nsISupports** variant = static_cast<nsISupports**>(aVariant.val.p);
        xpcom_obj = *variant;
      }

      nsID iid;
      rv = GetIIDForMethodParam(mIInfo, aMethodInfo, aParamInfo,
                                aParamInfo.GetType().TagPart(), aMethodIndex,
                                aDispatchParams, PR_FALSE, iid);
      if (NS_FAILED(rv))
        break;

      // get name of interface
      char* iface_name = nsnull;
      nsCOMPtr<nsIInterfaceInfoManager>
        iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv));
      if (NS_FAILED(rv))
        break;

      rv = iim->GetNameForIID(&iid, &iface_name);
      if (NS_FAILED(rv) || !iface_name)
        break;

      jobject java_stub = nsnull;
      if (xpcom_obj) {
        // Get matching Java object for given xpcom object
        jobject objLoader = env->CallObjectMethod(mJavaWeakRef, getReferentMID);
        rv = NativeInterfaceToJavaObject(env, xpcom_obj, iid, objLoader,
                                         &java_stub);
        if (NS_FAILED(rv))
          break;
      }

      if (!aParamInfo.IsOut()) {  // 'in'
        aJValue.l = java_stub;
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          aJValue.l = env->NewObjectArray(1, nsISupportsClass, java_stub);
          if (aJValue.l == nsnull) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.Append('[');
      }

      if (tag != nsXPTType::T_INTERFACE_IS) {
        aMethodSig.AppendLiteral("Lorg/mozilla/interfaces/");
        aMethodSig.AppendASCII(iface_name);
        aMethodSig.Append(';');
      } else {
        aMethodSig.AppendLiteral("Lorg/mozilla/interfaces/nsISupports;");
      }

      nsMemory::Free(iface_name);
    }
    break;

    case nsXPTType::T_ASTRING:
    case nsXPTType::T_DOMSTRING:
    {
      // This only handle 'in' or 'in dipper' params.  In XPIDL, the 'out'
      // descriptor is mapped to 'in dipper'.
      NS_PRECONDITION(aParamInfo.IsIn(), "unexpected param descriptor");
      if (!aParamInfo.IsIn()) {
        rv = NS_ERROR_UNEXPECTED;
        break;
      }

      nsString* str = static_cast<nsString*>(aVariant.val.p);
      if (!str) {
        rv = NS_ERROR_FAILURE;
        break;
      }

      jstring jstr = nsnull;
      if (!str->IsVoid()) {
        jstr = env->NewString(str->get(), str->Length());
        if (!jstr) {
          rv = NS_ERROR_OUT_OF_MEMORY;
          break;
        }
      }

      aJValue.l = jstr;
      aMethodSig.AppendLiteral("Ljava/lang/String;");
    }
    break;

    case nsXPTType::T_UTF8STRING:
    case nsXPTType::T_CSTRING:
    {
      // This only handle 'in' or 'in dipper' params.  In XPIDL, the 'out'
      // descriptor is mapped to 'in dipper'.
      NS_PRECONDITION(aParamInfo.IsIn(), "unexpected param descriptor");
      if (!aParamInfo.IsIn()) {
        rv = NS_ERROR_UNEXPECTED;
        break;
      }

      nsCString* str = static_cast<nsCString*>(aVariant.val.p);
      if (!str) {
        rv = NS_ERROR_FAILURE;
        break;
      }

      jstring jstr = nsnull;
      if (!str->IsVoid()) {
        jstr = env->NewStringUTF(str->get());
        if (!jstr) {
          rv = NS_ERROR_OUT_OF_MEMORY;
          break;
        }
      }

      aJValue.l = jstr;
      aMethodSig.AppendLiteral("Ljava/lang/String;");
    }
    break;

    // Pass the 'void*' address as a long
    case nsXPTType::T_VOID:
    {
      if (!aParamInfo.IsOut()) {  // 'in'
        aJValue.j = reinterpret_cast<jlong>(aVariant.val.p);
        aMethodSig.Append('J');
      } else {  // 'inout' & 'out'
        if (aVariant.val.p) {
          jlongArray array = env->NewLongArray(1);
          if (!array) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            break;
          }

          env->SetLongArrayRegion(array, 0, 1, (jlong*) aVariant.val.p);
          aJValue.l = array;
        } else {
          aJValue.l = nsnull;
        }
        aMethodSig.AppendLiteral("[J");
      }
    }
    break;

    case nsXPTType::T_ARRAY:
      NS_WARNING("array types are not yet supported");
      return NS_ERROR_NOT_IMPLEMENTED;
      break;

    case nsXPTType::T_PSTRING_SIZE_IS:
    case nsXPTType::T_PWSTRING_SIZE_IS:
    default:
      NS_WARNING("unexpected parameter type");
      return NS_ERROR_UNEXPECTED;
  }

  return rv;
}
Beispiel #9
0
NS_IMETHODIMP
nsJavaXPTCStub::QueryInterface(const nsID &aIID, void **aInstancePtr)
{
  nsresult rv;

  LOG(("JavaStub::QueryInterface()\n"));
  *aInstancePtr = nsnull;
  nsJavaXPTCStub *master = mMaster ? mMaster : this;

  // This helps us differentiate between the help classes.
  if (aIID.Equals(NS_GET_IID(nsJavaXPTCStub)))
  {
    *aInstancePtr = master;
    NS_ADDREF(this);
    return NS_OK;
  }

  // always return the master stub for nsISupports
  if (aIID.Equals(NS_GET_IID(nsISupports)))
  {
    *aInstancePtr = master->mXPTCStub;
    NS_ADDREF(master);
    return NS_OK;
  }

  // All Java objects support weak references
  if (aIID.Equals(NS_GET_IID(nsISupportsWeakReference)))
  {
    *aInstancePtr = static_cast<nsISupportsWeakReference*>(master);
    NS_ADDREF(master);
    return NS_OK;
  }

  // does any existing stub support the requested IID?
  nsJavaXPTCStub *stub = master->FindStubSupportingIID(aIID);
  if (stub)
  {
    *aInstancePtr = stub->mXPTCStub;
    NS_ADDREF(stub);
    return NS_OK;
  }

  JNIEnv* env = GetJNIEnv();

  // Query Java object
  LOG(("\tCalling Java object queryInterface\n"));
  jobject javaObject = env->CallObjectMethod(mJavaWeakRef, getReferentMID);

  jmethodID qiMID = 0;
  jclass clazz = env->GetObjectClass(javaObject);
  if (clazz) {
    char* sig = "(Ljava/lang/String;)Lorg/mozilla/interfaces/nsISupports;";
    qiMID = env->GetMethodID(clazz, "queryInterface", sig);
    NS_ASSERTION(qiMID, "Failed to get queryInterface method ID");
  }

  if (qiMID == 0) {
    env->ExceptionClear();
    return NS_NOINTERFACE;
  }

  // construct IID string
  jstring iid_jstr = nsnull;
  char* iid_str = aIID.ToString();
  if (iid_str) {
    iid_jstr = env->NewStringUTF(iid_str);
  }
  if (!iid_str || !iid_jstr) {
    env->ExceptionClear();
    return NS_ERROR_OUT_OF_MEMORY;
  }
  PR_Free(iid_str);

  // call queryInterface method
  jobject obj = env->CallObjectMethod(javaObject, qiMID, iid_jstr);
  if (env->ExceptionCheck()) {
    env->ExceptionClear();
    return NS_ERROR_FAILURE;
  }
  if (!obj)
    return NS_NOINTERFACE;

  // Get interface info for new java object
  nsCOMPtr<nsIInterfaceInfoManager>
    iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIInterfaceInfo> iinfo;
  rv = iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo));
  if (NS_FAILED(rv))
    return rv;

  stub = new nsJavaXPTCStub(obj, iinfo, &rv);
  if (!stub)
    return NS_ERROR_OUT_OF_MEMORY;

  if (NS_FAILED(rv)) {
    delete stub;
    return rv;
  }

  // add stub to the master's list of children, so we can preserve
  // symmetry in future QI calls.  the master will delete each child
  // when it is destroyed.  the refcount of each child is bound to
  // the refcount of the master.  this is done to deal with code
  // like this:
  //
  //   nsCOMPtr<nsIBar> bar = ...;
  //   nsIFoo *foo;
  //   {
  //     nsCOMPtr<nsIFoo> temp = do_QueryInterface(bar);
  //     foo = temp;
  //   }
  //   foo->DoStuff();
  //
  // while this code is not valid XPCOM (since it is using |foo|
  // after having called Release on it), such code is unfortunately
  // very common in the mozilla codebase.  the assumption this code
  // is making is that so long as |bar| is alive, it should be valid
  // to access |foo| even if the code doesn't own a strong reference
  // to |foo|!  clearly wrong, but we need to support it anyways.

  stub->mMaster = master;
  master->mChildren.AppendElement(stub);

  *aInstancePtr = stub->mXPTCStub;
  NS_ADDREF(stub);
  return NS_OK;
}
Beispiel #10
0
nsresult
nsJavaXPTCStub::GetRetvalSig(const nsXPTParamInfo* aParamInfo,
                             const XPTMethodDescriptor* aMethodInfo,
                             PRUint16 aMethodIndex,
                             nsXPTCMiniVariant* aDispatchParams,
                             nsACString &aRetvalSig)
{
  PRUint8 type = aParamInfo->GetType().TagPart();
  switch (type)
  {
    case nsXPTType::T_I8:
      aRetvalSig.Append('B');
      break;

    case nsXPTType::T_I16:
    case nsXPTType::T_U8:
      aRetvalSig.Append('S');
      break;

    case nsXPTType::T_I32:
    case nsXPTType::T_U16:
      aRetvalSig.Append('I');
      break;

    case nsXPTType::T_I64:
    case nsXPTType::T_U32:
      aRetvalSig.Append('J');
      break;

    case nsXPTType::T_FLOAT:
      aRetvalSig.Append('F');
      break;

    case nsXPTType::T_U64:
    case nsXPTType::T_DOUBLE:
      aRetvalSig.Append('D');
      break;

    case nsXPTType::T_BOOL:
      aRetvalSig.Append('Z');
      break;

    case nsXPTType::T_CHAR:
    case nsXPTType::T_WCHAR:
      aRetvalSig.Append('C');
      break;

    case nsXPTType::T_CHAR_STR:
    case nsXPTType::T_WCHAR_STR:
    case nsXPTType::T_IID:
    case nsXPTType::T_ASTRING:
    case nsXPTType::T_DOMSTRING:
    case nsXPTType::T_UTF8STRING:
    case nsXPTType::T_CSTRING:
      aRetvalSig.AppendLiteral("Ljava/lang/String;");
      break;

    case nsXPTType::T_INTERFACE:
    {
      nsID iid;
      nsresult rv = GetIIDForMethodParam(mIInfo, aMethodInfo, *aParamInfo, type,
                                         aMethodIndex, aDispatchParams,
                                         PR_FALSE, iid);
      if (NS_FAILED(rv))
        break;

      // get name of interface
      char* iface_name = nsnull;
      nsCOMPtr<nsIInterfaceInfoManager>
        iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv));
      if (NS_FAILED(rv))
        break;

      rv = iim->GetNameForIID(&iid, &iface_name);
      if (NS_FAILED(rv) || !iface_name)
        break;

      aRetvalSig.AppendLiteral("Lorg/mozilla/interfaces/");
      aRetvalSig.AppendASCII(iface_name);
      aRetvalSig.Append(';');
      nsMemory::Free(iface_name);
      break;
    }

    case nsXPTType::T_INTERFACE_IS:
      aRetvalSig.AppendLiteral("Lorg/mozilla/interfaces/nsISupports;");
      break;

    case nsXPTType::T_VOID:
      aRetvalSig.Append('J');
      break;

    case nsXPTType::T_ARRAY:
      NS_WARNING("array types are not yet supported");
      return NS_ERROR_NOT_IMPLEMENTED;
      break;

    case nsXPTType::T_PSTRING_SIZE_IS:
    case nsXPTType::T_PWSTRING_SIZE_IS:
    default:
      NS_WARNING("unexpected parameter type");
      return NS_ERROR_UNEXPECTED;
  }

  return NS_OK;
}
Beispiel #11
0
int main (int argc, char **argv) {
    int i;
    nsIID *iid1, *iid2, *iid3;
    char *name1, *name2, *name3;
    nsIInterfaceInfo *info2, *info3, *info4, *info5;

    nsCOMPtr<nsIInterfaceInfoManager> iim
        (do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));

    fprintf(stderr, "\ngetting iid for 'nsISupports'\n");
    iim->GetIIDForName("nsISupports", &iid1);
    iim->GetNameForIID(iid1, &name1);
    fprintf(stderr, "%s iid %s\n", name1, iid1->ToString());

    fprintf(stderr, "\ngetting iid for 'nsIInputStream'\n");
    iim->GetIIDForName("nsIInputStream", &iid2);
    iim->GetNameForIID(iid2, &name2);
    fprintf(stderr, "%s iid %s\n", name2, iid2->ToString());

    fprintf(stderr, "iid: %s, name: %s\n", iid1->ToString(), name1);
    fprintf(stderr, "iid: %s, name: %s\n", iid2->ToString(), name2);

    fprintf(stderr, "\ngetting info for iid2 from above\n");
    iim->GetInfoForIID(iid2, &info2);
#ifdef DEBUG
//    ((nsInterfaceInfo *)info2)->print(stderr);
#endif

    fprintf(stderr, "\ngetting iid for 'nsIInputStream'\n");
    iim->GetIIDForName("nsIInputStream", &iid3);
    iim->GetNameForIID(iid3, &name3);
    fprintf(stderr, "%s iid %s\n", name3, iid2->ToString());
    iim->GetInfoForIID(iid3, &info3);
#ifdef DEBUG
//    ((nsInterfaceInfo *)info3)->print(stderr);
#endif

    fprintf(stderr, "\ngetting info for name 'nsIBidirectionalEnumerator'\n");
    iim->GetInfoForName("nsIBidirectionalEnumerator", &info4);
#ifdef DEBUG
//    ((nsInterfaceInfo *)info4)->print(stderr);
#endif

    fprintf(stderr, "\nparams work?\n");
    fprintf(stderr, "\ngetting info for name 'nsIServiceManager'\n");
    iim->GetInfoForName("nsIServiceManager", &info5);
#ifdef DEBUG
//    ((nsInterfaceInfo *)info5)->print(stderr);
#endif

    // XXX: nsIServiceManager is no more; what do we test with?
    if (info5 == NULL) {
        fprintf(stderr, "\nNo nsIServiceManager; cannot continue.\n");
        return 1;
    }

    uint16 methodcount;
    info5->GetMethodCount(&methodcount);
    const nsXPTMethodInfo *mi;
    for (i = 0; i < methodcount; i++) {
        info5->GetMethodInfo(i, &mi);
        fprintf(stderr, "method %d, name %s\n", i, mi->GetName());
    }

    // 7 is GetServiceWithListener, which has juicy params.
    info5->GetMethodInfo(7, &mi);
//    uint8 paramcount = mi->GetParamCount();

    nsXPTParamInfo param2 = mi->GetParam(2);
    // should be IID for nsIShutdownListener
    nsIID *nsISL;
    info5->GetIIDForParam(7, &param2, &nsISL);
//      const nsIID *nsISL = param2.GetInterfaceIID(info5);
    fprintf(stderr, "iid assoc'd with param 2 of method 7 of GetServiceWithListener - %s\n", nsISL->ToString());
    // if we look up the name?
    char *nsISLname;
    iim->GetNameForIID(nsISL, &nsISLname);
    fprintf(stderr, "which is called %s\n", nsISLname);

    fprintf(stderr, "\nhow about one defined in a different typelib\n");
    nsXPTParamInfo param3 = mi->GetParam(3);
    // should be IID for nsIShutdownListener
    nsIID *nsISS;
    info5->GetIIDForParam(7, &param3, &nsISS);
//      const nsIID *nsISS = param3.GetInterfaceIID(info5);
    fprintf(stderr, "iid assoc'd with param 3 of method 7 of GetServiceWithListener - %s\n", nsISS->ToString());
    // if we look up the name?
    char *nsISSname;
    iim->GetNameForIID(nsISS, &nsISSname);
    fprintf(stderr, "which is called %s\n", nsISSname);

    return 0;
}