validateEngineNow(theEngine);  if (updateSearchEngineFile == PR_TRUE) { #ifdef	DEBUG_SEARCH_UPDATES printf("    Search engine='%s' needs updating, so fetching it\n", engineURI); #endif  nsCString		updateURL; nsCOMPtr<nsIRDFNode>	aNode; if (NS_SUCCEEDED(rv = mInner->GetTarget(theEngine, kNC_Update, PR_TRUE, getter_AddRefs(aNode))) && (rv != NS_RDF_NO_VALUE)) { nsCOMPtr<nsIRDFLiteral>	aLiteral (do_QueryInterface(aNode)); if (aLiteral) { const PRUnichar	*updateUni = nsnull; aLiteral->GetValueConst(&updateUni); if (updateUni) { updateURL.AssignWithConversion(updateUni); } } }   nsCString		updateIconURL; if (NS_SUCCEEDED(rv = mInner->GetTarget(theEngine, kNC_UpdateIcon, PR_TRUE, getter_AddRefs(aNode))) && (rv != NS_RDF_NO_VALUE)) { nsCOMPtr<nsIRDFLiteral>	aIconLiteral (do_QueryInterface(aNode)); if (aIconLiteral) { const PRUnichar	*updateIconUni = nsnull; aIconLiteral->GetValueConst(&updateIconUni); if (updateIconUni) { updateIconURL.AssignWithConversion(updateIconUni); } } }   AddSearchEngine(updateURL.get(), updateIconURL.get(), nsnull, nsnull); } else { #ifdef	DEBUG_SEARCH_UPDATES printf("    Search engine='%s' is current and requires no updating\n", engineURI); #endif } } else { rv = NS_ERROR_UNEXPECTED; } return(rv);
PRInt32	anchorEnd = resultItem.FindCharInSet(">", quoteEndOffset); if (anchorEnd < quoteEndOffset) { #ifdef	DEBUG_SEARCH_OUTPUT printf("\n\nSearch: Unable to find ending > when computing name.\n\n"); #endif continue; }  PRInt32	anchorStop = resultItem.Find("</A>", PR_TRUE, quoteEndOffset); if (anchorStop < anchorEnd) { #ifdef	DEBUG_SEARCH_OUTPUT printf("\n\nSearch: Unable to find </A> tag to compute name.\n\n"); #endif continue; }  nsAutoString	nameStr; resultItem.Mid(nameStr, anchorEnd + 1, anchorStop - anchorEnd - 1);   PRInt32	quotOffset; while ((quotOffset = nameStr.Find("&quot;", PR_TRUE)) >= 0) { nameStr.Cut(quotOffset, strlen("&quot;")); nameStr.Insert(PRUnichar('\"'), quotOffset); }   PRInt32	ampOffset; while ((ampOffset = nameStr.Find("&amp;", PR_TRUE)) >= 0) { nameStr.Cut(ampOffset, strlen("&amp;")); nameStr.Insert(PRUnichar('&'), ampOffset); }   PRInt32	nbspOffset; while ((nbspOffset = nameStr.Find("&nbsp;", PR_TRUE)) >= 0) { nameStr.Cut(nbspOffset, strlen("&nbsp;")); nameStr.Insert(PRUnichar(' '), nbspOffset); }   PRInt32	ltOffset; while ((ltOffset = nameStr.Find("&lt;", PR_TRUE)) >= 0) { nameStr.Cut(ltOffset, strlen("&lt;")); nameStr.Insert(PRUnichar('<'), ltOffset); }   PRInt32	gtOffset; while ((gtOffset = nameStr.Find("&gt;", PR_TRUE)) >= 0) { nameStr.Cut(gtOffset, strlen("&gt;")); nameStr.Insert(PRUnichar('>'), gtOffset); }   PRInt32 tagStartOffset; while ((tagStartOffset = nameStr.FindCharInSet("<", 0)) >= 0) { PRInt32	tagEndOffset = nameStr.FindCharInSet(">", tagStartOffset); if (tagEndOffset <= tagStartOffset)	break; nameStr.Cut(tagStartOffset, tagEndOffset - tagStartOffset + 1); }   PRInt32	eolOffset; while ((eolOffset = nameStr.FindCharInSet("\n\r", 0)) >= 0) { nameStr.Cut(eolOffset, 1); }  nameStr = nameStr.Trim(" \t");   nsCOMPtr<nsIRDFNode>		oldNameRes = nsnull; mInner->GetTarget(res, kNC_Name, PR_TRUE, getter_AddRefs(oldNameRes)); if (!oldNameRes) { if (nameStr.Length() > 0) { const PRUnichar	*nameUni = nameStr.GetUnicode(); if (nameUni) { nsCOMPtr<nsIRDFLiteral>	nameLiteral; if (NS_SUCCEEDED(rv = gRDFService->GetLiteral(nameUni, getter_AddRefs(nameLiteral)))) { if (nameLiteral) { mInner->Assert(res, kNC_Name, nameLiteral, PR_TRUE); } } } } }   nsAutoString	relItem; PRInt32		relStart; if ((relStart = resultItem.Find(relevanceStartStr, PR_TRUE)) >= 0) { PRInt32	relEnd = resultItem.Find(relevanceEndStr, PR_TRUE); if (relEnd > relStart) { resultItem.Mid(relItem, relStart + relevanceStartStr.Length(), relEnd - relStart - relevanceStartStr.Length()); } }   nsCOMPtr<nsIRDFNode>		oldRelRes = nsnull; mInner->GetTarget(res, kNC_Relevance, PR_TRUE, getter_AddRefs(oldRelRes)); if (!oldRelRes) { if (relItem.Length() > 0) {  const PRUnichar	*relUni = relItem.GetUnicode(); if (relUni) { nsAutoString	relStr(relUni);  PRInt32	len = relStr.Length(); for (PRInt32 x=len-1; x>=0; x--) { PRUnichar	ch; ch = relStr.CharAt(x); if ((ch != PRUnichar('%')) && ((ch < PRUnichar('0')) || (ch > PRUnichar('9')))) { relStr.Cut(x, 1); } }  len = relStr.Length(); if (len > 0) { PRUnichar	ch; ch = relStr.CharAt(len - 1); if (ch != PRUnichar('%')) { relStr += PRUnichar('%'); } relItem = relStr; } else { relItem.Truncate(); } } } if (relItem.Length() < 1) { relItem = "-"; }  const PRUnichar *relItemUni = relItem.GetUnicode(); nsCOMPtr<nsIRDFLiteral>	relLiteral; if (NS_SUCCEEDED(rv = gRDFService->GetLiteral(relItemUni, getter_AddRefs(relLiteral)))) { if (relLiteral) { mInner->Assert(res, kNC_Relevance, relLiteral, PR_TRUE); } }  if ((relItem.Length() > 0) && (!relItem.Equals("-"))) {  if (relItem[relItem.Length()-1] == PRUnichar('%')) { relItem.Cut(relItem.Length()-1, 1); }   nsAutoString	zero("000"); if (relItem.Length() < 3) { relItem.Insert(zero, 0, zero.Length() - relItem.Length()); } } else { relItem = "000"; }  const PRUnichar	*relSortUni = relItem.GetUnicode(); if (relSortUni) { nsCOMPtr<nsIRDFLiteral>	relSortLiteral; if (NS_SUCCEEDED(rv = gRDFService->GetLiteral(relSortUni, getter_AddRefs(relSortLiteral)))) { if (relSortLiteral) { mInner->Assert(res, kNC_RelevanceSort, relSortLiteral, PR_TRUE); } } } }   nsCOMPtr<nsIRDFNode>		oldEngineRes = nsnull; mInner->GetTarget(res, kNC_Engine, PR_TRUE, getter_AddRefs(oldEngineRes)); if (!oldEngineRes) { nsAutoString	engineStr; if (NS_SUCCEEDED(rv = InternetSearchDataSource::GetData(data, "search", "name", engineStr))) { const PRUnichar		*engineUni = engineStr.GetUnicode(); nsCOMPtr<nsIRDFLiteral>	engineLiteral; if (NS_SUCCEEDED(rv = gRDFService->GetLiteral(engineUni, getter_AddRefs(engineLiteral)))) { if (engineLiteral) { mInner->Assert(res, kNC_Engine, engineLiteral, PR_TRUE); } } } }   nsCOMPtr<nsIRDFNode>		engineIconNode = nsnull; mInner->GetTarget(mEngine, kNC_Icon, PR_TRUE, getter_AddRefs(engineIconNode)); if (engineIconNode) { rv = mInner->Assert(res, kNC_Icon, engineIconNode, PR_TRUE); }  #ifdef	OLDWAY  PRBool		parentHasChildFlag = PR_FALSE; mInner->HasAssertion(mParent, kNC_Child, res, PR_TRUE, &parentHasChildFlag); if (parentHasChildFlag == PR_FALSE) #endif { rv = mInner->Assert(mParent, kNC_Child, res, PR_TRUE); }   if (mInner) { rv = mInner->Assert(kNC_LastSearchRoot, kNC_Child, res, PR_TRUE); }  } return(NS_OK);
InternetSearchDataSource::OnStopRequest(nsIRequest *request, nsISupports *ctxt,                                        nsresult status){	if (!mInner)	return(NS_OK);  nsCOMPtr<nsIChannel> channel (do_QueryInterface(request));	nsCOMPtr<nsIInternetSearchContext> context (do_QueryInterface(ctxt));	if (!ctxt)	return(NS_ERROR_NO_INTERFACE);	nsresult	rv;	PRUint32	contextType = 0;	if (NS_FAILED(rv = context->GetContextType(&contextType)))		return(rv);	if (contextType == nsIInternetSearchContext::WEB_SEARCH_CONTEXT)	{		// continue to process nsIInternetSearchContext::WEB_SEARCH_CONTEXT		rv = webSearchFinalize(channel, context);	}	else if (contextType == nsIInternetSearchContext::ENGINE_DOWNLOAD_CONTEXT ||		 contextType == nsIInternetSearchContext::ICON_DOWNLOAD_CONTEXT)	{		nsCOMPtr<nsIHttpChannel> httpChannel (do_QueryInterface(channel));		if (!httpChannel)	return(NS_ERROR_UNEXPECTED);		// check HTTP status to ensure success		PRUint32	httpStatus = 0;		if (NS_SUCCEEDED(rv = httpChannel->GetResponseStatus(&httpStatus)) &&			(httpStatus == 200))		{			rv = saveContents(channel, context, contextType);		}	}	else if (contextType == nsIInternetSearchContext::ENGINE_UPDATE_CONTEXT)	{		nsCOMPtr<nsIRDFResource>	theEngine;		if (NS_FAILED(rv = context->GetEngine(getter_AddRefs(theEngine))))	return(rv);		if (!theEngine)	return(NS_ERROR_NO_INTERFACE);#ifdef	DEBUG_SEARCH_UPDATES		const char	*engineURI = nsnull;		theEngine->GetValueConst(&engineURI);#endif		// free up "busy" info now & mark as non-busy		busySchedule = PR_FALSE;		busyResource = nsnull;		// we only have HTTP "HEAD" information when doing updates		nsCOMPtr<nsIHttpChannel> httpChannel (do_QueryInterface(channel));		if (!httpChannel)	return(NS_ERROR_UNEXPECTED);		// check HTTP status to ensure success		PRUint32	httpStatus = 0;		if (NS_FAILED(rv = httpChannel->GetResponseStatus(&httpStatus)))			return(rv);		if (httpStatus != 200)	return(NS_ERROR_UNEXPECTED);		// get last-modified & content-length info		nsCAutoString			lastModValue, contentLengthValue;        if (NS_FAILED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Last-Modified"), lastModValue)))            lastModValue.Truncate();        if (NS_FAILED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Length"), contentLengthValue)))            contentLengthValue.Truncate();		// should we fetch the entire file?		PRBool		updateSearchEngineFile = PR_FALSE;		// save out new search engine state data into localstore		PRBool			tempDirty = PR_FALSE;		nsCOMPtr<nsIRDFLiteral>	newValue;		if (lastModValue.Length() > 0)		{			gRDFService->GetLiteral(NS_ConvertASCIItoUCS2(lastModValue).get(),				getter_AddRefs(newValue));			if (newValue)			{				updateAtom(mLocalstore, theEngine, kWEB_LastPingModDate, newValue,					&tempDirty);				if (tempDirty == PR_TRUE)	updateSearchEngineFile = PR_TRUE;			}		}		if (contentLengthValue.Length() > 0)		{			gRDFService->GetLiteral(NS_ConvertASCIItoUCS2(contentLengthValue).get(),				getter_AddRefs(newValue));			if (newValue)			{				updateAtom(mLocalstore, theEngine, kWEB_LastPingContentLen, newValue,					&tempDirty);				if (tempDirty == PR_TRUE)				{					updateSearchEngineFile = PR_TRUE;				}				else				{					// worst case: compare local data size vs. remote content size					nsCOMPtr<nsIRDFLiteral>	dataLit;					if (NS_SUCCEEDED(rv = FindData(theEngine, getter_AddRefs(dataLit))) &&						(rv != NS_RDF_NO_VALUE))					{						const PRUnichar	*dataUni = nsnull;						dataLit->GetValueConst(&dataUni);						nsAutoString	dataStr(dataUni);						PRInt32		dataLen=dataStr.Length();#ifdef	DEBUG_SEARCH_UPDATES						printf("    Search engine='%s' data length='%d'\n", engineURI, dataLen);#endif						PRInt32	contentLen=0, err=0;						contentLen = contentLengthValue.ToInteger(&err);						if ((!err) && (dataLen != contentLen))						{#ifdef	DEBUG_SEARCH_UPDATES							printf("    Search engine '%s' data length != remote content length, so update\n",								engineURI, dataLen);#endif							updateSearchEngineFile = PR_TRUE;						}					}				}			}		}		// mark now as the last time we stat'ted the search engine		validateEngineNow(theEngine);		if (updateSearchEngineFile == PR_TRUE)		{#ifdef	DEBUG_SEARCH_UPDATES			printf("    Search engine='%s' needs updating, so fetching it\n", engineURI);#endif			// get update URL			nsCString		updateURL;			nsCOMPtr<nsIRDFNode>	aNode;			if (NS_SUCCEEDED(rv = mInner->GetTarget(theEngine, kNC_Update, PR_TRUE, getter_AddRefs(aNode)))				&& (rv != NS_RDF_NO_VALUE))			{				nsCOMPtr<nsIRDFLiteral>	aLiteral (do_QueryInterface(aNode));				if (aLiteral)				{					const PRUnichar	*updateUni = nsnull;					aLiteral->GetValueConst(&updateUni);					if (updateUni)					{						updateURL.AssignWithConversion(updateUni);					}				}			}			// get update icon			nsCString		updateIconURL;			if (NS_SUCCEEDED(rv = mInner->GetTarget(theEngine, kNC_UpdateIcon, PR_TRUE, getter_AddRefs(aNode)))				&& (rv != NS_RDF_NO_VALUE))			{				nsCOMPtr<nsIRDFLiteral>	aIconLiteral (do_QueryInterface(aNode));				if (aIconLiteral)				{					const PRUnichar	*updateIconUni = nsnull;					aIconLiteral->GetValueConst(&updateIconUni);					if (updateIconUni)					{						updateIconURL.AssignWithConversion(updateIconUni);					}				}			}			// download it!			AddSearchEngine(updateURL.get(), updateIconURL.get(), nsnull, nsnull);		}		else		{#ifdef	DEBUG_SEARCH_UPDATES			printf("    Search engine='%s' is current and requires no updating\n", engineURI);#endif		}	}	else	{		rv = NS_ERROR_UNEXPECTED;	}	return(rv);}