Esempio n. 1
0
//	Find the contact matching the JID and update the contact resource (if any).
//	If the JID is not in the contact list, the method will create a new contact to the list according to the value of eFindContact.
//	This method may return NULL if the JID is empty/invalid because a new contact cannot not be created.
//
//	IMPLEMENTATION NOTES
//	This method should use a hash table to quickly find a contact from its JID and/or use a pointer to cache the last contact found.
TContact *
TAccountXmpp::Contact_PFindByJID(PSZUC pszContactJID, EFindContact eFindContact)
	{
	Assert(pszContactJID != NULL);
	if (pszContactJID != NULL)
		{
		// Find the resource
		PSZUC pszResource = pszContactJID;
		while (TRUE)
			{
			if (*pszResource == '/')
				break;
			if (*pszResource == '\0')
				break;
			pszResource++;
			} // while
		const int cchJID = pszResource - pszContactJID;
		if (cchJID > 0)
			{
			TContact * pContact;
			TContact ** ppContactStop;
			TContact ** ppContact = m_arraypaContacts.PrgpGetContactsStop(OUT &ppContactStop);
			while (ppContact != ppContactStop)
				{
				pContact = *ppContact++;
//				Assert(!m_strJID.FCompareStringsJIDs(pContact->m_strJidBare) && "Contact should not have the same JID as its parent XMPP account!");
				//MessageLog_AppendTextFormatCo(d_coBlack, "Comparing $s with $S\n", pszContactJID, &pContact->m_strJidBare);
				if (pContact->m_strJidBare.FCompareStringsNoCaseCch(pszContactJID, cchJID))
					{
					// We have found our contact
					if (pContact->TreeItemFlags_FuIsInvisible())
						{
						Endorse(pContact->m_paTreeItemW_YZ != NULL);	// Typically an invisible contact should not appear in the Navigation Tree, however there are situations where it is. For instance, if the contact was just deleted, or if displayed into the list of "Deleted Items"
						if (eFindContact & eFindContact_kfMakeVisible)
							pContact->TreeItemContact_DisplayWithinNavigationTreeAndClearInvisibleFlag();
						}
					if (*pszResource != '\0')
						{
						// Update the contact resource
						if (!pContact->m_strRessource.FCompareStringsExactCase(pszResource))
							{
							if (pContact->m_strRessource.FIsEmptyString())
								MessageLog_AppendTextFormatCo(d_coBlack, "Contact $S: Assigning resource '$s' (m_uFlagsTreeItem = 0x$x)\n", &pContact->m_strJidBare, pszResource, m_uFlagsTreeItem);
							else
								MessageLog_AppendTextFormatCo(COX_MakeBold(d_coBlack), "Contact $S: Updating resource from '$S' to '$s'\n", &pContact->m_strJidBare, &pContact->m_strRessource, pszResource);
							//pContact->Xcp_ServiceDiscovery();	// The resource changed, therefore query the remote client for its capabilities
							pContact->SetFlagXcpComposingSendTimestampsOfLastKnownEvents();	// Each time the resource change, re-send the timestamps of the last known events so we give an opportunity to synchronize
							//pContact->m_cVersionXCP = 0;	// Also, reset the XCP version, to make sure the device connects properly
							}
						pContact->m_strRessource.InitFromStringU(pszResource);
						}
					return pContact;
					}
				} // while
			// We could not find the contact, so create a new one if the JID meets the minimal conditions
			if ((eFindContact & eFindContact_kfCreateNew) &&
				PcheValidateJID(pszContactJID) == NULL &&			// Make sure the JID is somewhat valid to create a new contact
				!m_strJID.FCompareStringsJIDs(pszContactJID))		// Make sure the JID is not the same as the account.  It makes no sense to create a contact with the same JID as its parent account.  This situation occurs rarely when the server sends a stanza where the 'from' contains the JID of the account.
				{
				MessageLog_AppendTextFormatSev(eSeverityInfoTextBlack, "Contact_PFindByJID('$s') - Creating contact for account $S\n", pszContactJID, &m_strJID);
				pContact = TreeItemAccount_PContactAllocateNewToNavigationTree_NZ(IN pszContactJID);
				if (eFindContact & eFindContact_kfCreateAsUnsolicited)
					pContact->SetFlagContactAsUnsolicited();
				return pContact;
				}
			} // if
		} // if
	return NULL;
	} // Contact_PFindByJID()