if (values != autovalues) delete[] values;
nsHTTPIndexParser::ParseData(const char* aDataStr, nsISupports *context){  // Parse a "201" data line, using the field ordering specified in  // mFormat.  if (mFormat.Count() == 0) {    // Ignore if we haven't seen a format yet.    return NS_OK;  }  // Because the 'file:' protocol won't do this for us, we need to  // make sure that the mDirectoryURI ends with a '/' before  // concatenating.  nsresult rv;  NS_WITH_SERVICE(nsITextToSubURI, textToSubURI, kTextToSubURICID, &rv);  NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get nsITextToSubURI service");  nsCOMPtr<nsIURI> realbase;  {      nsXPIDLCString orig;      rv = mDirectoryURI->GetSpec(getter_Copies(orig));      if (NS_FAILED(rv)) return rv;      nsCAutoString basestr(orig);      if (basestr.Last() != '/')        basestr.Append('/');      rv = NS_NewURI(getter_AddRefs(realbase), (const char*) basestr);      if (NS_FAILED(rv)) return rv;  }  // First, we'll iterate through the values and remember each (using  // an array of autostrings allocated on the stack, if possible). We  // have to do this, because we don't know up-front the filename for  // which this 201 refers.#define MAX_AUTO_VALUES 8  nsAutoString autovalues[MAX_AUTO_VALUES];  nsAutoString* values = autovalues;  if (mFormat.Count() > MAX_AUTO_VALUES) {    // Yeah, we really -do- want to create nsAutoStrings in the heap    // here, because most of the fields will be l.t. 32 characters:    // this avoids an extra allocation for the nsString's buffer.    values = new nsAutoString[mFormat.Count()];    if (! values)      return NS_ERROR_OUT_OF_MEMORY;  }  rv = NS_OK;  nsCOMPtr<nsIRDFResource> entry;    nsCAutoString	filename, filetype;    nsXPIDLCString  encodingStr;	if (mHTTPIndex)	{	    mHTTPIndex->GetEncoding(getter_Copies(encodingStr));	}  for (PRInt32 i = 0; i < mFormat.Count(); ++i) {    // If we've exhausted the data before we run out of fields, just    // bail.    if (! *aDataStr)      break;    while (*aDataStr && nsCRT::IsAsciiSpace(PRUnichar(*aDataStr)))      ++aDataStr;    nsCAutoString	value;    PRInt32		len;    if (*aDataStr == '"' || *aDataStr == '\'') {      // it's a quoted string. snarf everything up to the next quote character      const char quotechar = *(aDataStr++);      len = 0;      while (aDataStr[len] && (aDataStr[len] != quotechar))      	++len;      value.SetCapacity(len + 1);      value.Append(aDataStr, len);      aDataStr += len;      if (! aDataStr) {        NS_WARNING("quoted value not terminated");      }    }    else {      // it's unquoted. snarf until we see whitespace.      len = 0;      while (aDataStr[len] && !nsCRT::IsAsciiSpace(aDataStr[len]))        ++len;      value.SetCapacity(len + 1);      value.Append(aDataStr, len);      aDataStr += len;    }    Field* field = NS_STATIC_CAST(Field*, mFormat.ElementAt(i));    if (field && field->mProperty == kHTTPIndex_Filename)    {        // don't unescape at this point, so that UnEscapeAndConvert() can        filename = value.mStr;        PRBool  success = PR_FALSE;        nsAutoString entryuri;        if (textToSubURI)        {            PRUnichar	*result = nsnull;            if (NS_SUCCEEDED(rv = textToSubURI->UnEscapeAndConvert(encodingStr, filename,                &result)) && (result))            {                if (nsCRT::strlen(result) > 0)                {                    values[i].Append(result);                    success = PR_TRUE;                }                Recycle(result);            }            else            {                NS_WARNING("UnEscapeAndConvert error");            }        }        if (success == PR_FALSE)        {            // if unsuccessfully at charset conversion, then            // just fallback to unescape'ing the nsStr (in place)            value.mLength = nsUnescapeCount(value.mStr);            values[i].AppendWithConversion(value);        }    }    else    {        // unescape the nsStr (in place)        value.mLength = nsUnescapeCount(value.mStr);        values[i].AppendWithConversion(value);        if (field && field->mProperty == kHTTPIndex_Filetype)        {            filetype = value.mStr;        }    }  }      // we found the filename; construct a resource for its entry        nsAutoString    entryuri;        rv = NS_MakeAbsoluteURI(entryuri, NS_ConvertASCIItoUCS2(filename), realbase);        NS_ASSERTION(NS_SUCCEEDED(rv), "unable make absolute URI");      // if its a directory, make sure it ends with a trailing slash      if (filetype.EqualsIgnoreCase("directory"))      {            entryuri.Append(PRUnichar('/'));      }      nsCAutoString entryuriC;      entryuriC.AssignWithConversion(entryuri);      rv = gRDF->GetResource(entryuriC, getter_AddRefs(entry));  // At this point, we'll (hopefully) have found the filename and  // constructed a resource for it, stored in entry. So now take a  // second pass through the values and add as statements to the RDF  // datasource.  if (entry && NS_SUCCEEDED(rv)) {    for (PRInt32 indx = 0; indx < mFormat.Count(); ++indx) {      Field* field = NS_REINTERPRET_CAST(Field*, mFormat.ElementAt(indx));      if (! field)        continue;      nsCOMPtr<nsIRDFNode> value;      rv = (*field->mParse)(field->mProperty, values[indx], getter_AddRefs(value));      if (NS_FAILED(rv)) break;      if (value)      {        rv = mDataSource->Assert(entry, field->mProperty, value, PR_TRUE);        if (NS_FAILED(rv)) break;      }    }	if (!mDirectoryContainer)	{		nsCOMPtr<nsIRDFResource>	parentRes = do_QueryInterface(context);		if (parentRes)		{			NS_WITH_SERVICE(nsIRDFContainerUtils, rdfc, "component://netscape/rdf/container-utils", &rv);			if (NS_FAILED(rv)) return rv;			rv = rdfc->MakeSeq(mDataSource, parentRes, getter_AddRefs(mDirectoryContainer));			if (NS_FAILED(rv)) return rv;		}	}	if (mDirectoryContainer)	{	    rv = mDirectoryContainer->AppendElement(entry);	}  }  // If we needed to spill values onto the heap, make sure we clean up  // here.  if (values != autovalues)    delete[] values;  return rv;}