static const PRInt32 kEscapeConservatively = esc_Forced - 1;    nsCAutoString escaped; nsresult rv = nsStdEscape(spec.get(), kEscapeConservatively, escaped); if (NS_FAILED(rv)) return rv; spec = escaped;
NS_MakeAbsoluteURIWithCharset(char* *aResult,                              const nsString& aSpec,                              nsIDocument* aDocument,                              nsIURI* aBaseURI,                              nsIIOService* aIOService,                              nsICharsetConverterManager* aConvMgr){  // Initialize aResult in case of tragedy  *aResult = nsnull;  // Sanity  NS_PRECONDITION(aBaseURI != nsnull, "no base URI");  if (! aBaseURI)    return NS_ERROR_FAILURE;  // This gets the relative spec after gyrating it through all the  // necessary encodings and escaping.  nsCAutoString spec;  if (nsCRT::IsAscii(aSpec.get())) {    // If it's ASCII, then just copy the characters    spec.AssignWithConversion(aSpec);  }  else {    // If the scheme is javascript then no charset conversion is needed,    // escape non ASCII in \uxxxx form.    PRInt32 pos = aSpec.FindChar(':');    static const char kJavaScript[] = "javascript";    nsAutoString scheme;    if ((pos == (PRInt32)(sizeof kJavaScript - 1)) &&        (aSpec.Left(scheme, pos)) &&         scheme.EqualsIgnoreCase(kJavaScript)) {      char buf[6+1];	// space for \uXXXX plus a NUL at the end      spec.Truncate(0);      for (const PRUnichar* uch = aSpec.get(); *uch; ++uch) {        if (!nsCRT::IsAscii(*uch)) {          PR_snprintf(buf, sizeof(buf), "\\u%.4x", *uch);          spec.Append(buf);        }        else {          spec.AppendWithConversion(*uch);        }      }    }    else {      // If the scheme is mailtourl then should not convert to a document charset      // because the charset cannot be passes to mailnews code,       // use UTF-8 instead and apply URL escape.      static const char kMailToURI[] = "mailto";      if ((pos == (PRInt32)(sizeof kMailToURI - 1)) &&          (aSpec.Left(scheme, pos)) &&           scheme.EqualsIgnoreCase(kMailToURI)) {        spec = NS_ConvertUCS2toUTF8(aSpec.get());      }      else {        // Otherwise, we'll need to use aDocument to cough up a character        // set converter, and re-encode the relative portion of the URL as        // 8-bit characters.        nsCOMPtr<nsIUnicodeEncoder> encoder;        if (aDocument) {          nsCOMPtr<nsICharsetConverterManager> convmgr;          if (aConvMgr) {            convmgr = aConvMgr;          }          else {            convmgr = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID);          }          if (! convmgr)            return NS_ERROR_FAILURE;          nsAutoString charSetID;          aDocument->GetDocumentCharacterSet(charSetID);          convmgr->GetUnicodeEncoder(&charSetID, getter_AddRefs(encoder));        }        if (encoder) {          // Got the encoder: let's party.          PRInt32 len = aSpec.Length();          PRInt32 maxlen;          encoder->GetMaxLength(aSpec.get(), len, &maxlen);          char buf[64], *p = buf;          if (PRUint32(maxlen) > sizeof(buf) - 1)            p = new char[maxlen + 1];          if (! p)            return NS_ERROR_OUT_OF_MEMORY;          encoder->Convert(aSpec.get(), &len, p, &maxlen);          p[maxlen] = 0;          spec = p;          encoder->Finish(p, &len);          p[len] = 0;          spec += p;          if (p != buf)            delete[] p;          // iDNS support: encode the hostname in the URL to UTF8          nsresult rv;          nsXPIDLCString newSpec;          rv = ConvertHostnameToUTF8(getter_Copies(newSpec), spec.get(), aSpec, aIOService);          if (NS_FAILED(rv))            return rv;          if (!newSpec.IsEmpty()) // hostname is non-ASCII            spec = newSpec;        }        else {          // No encoder, but we've got non-ASCII data. Let's UTF-8 encode          // by default.          spec = NS_ConvertUCS2toUTF8(aSpec.get());        }      }      // Now we need to URL-escape the string.       // XXX andreas.otte has warned that using the nsIIOService::Escape      // method in this way may be too conservative (e.g., it won't      // escape a "#" character that appears in a hostname -- does that      // matter?) But, since there's nothing better, we'll do it...      static const PRInt32 kEscapeConservatively = esc_Forced - 1;      // XXX Unfortunately, we can't escape "in place". Maybe the new string      // APIs will make that better some day.      nsCAutoString escaped;      nsresult rv = nsStdEscape(spec.get(), kEscapeConservatively, escaped);      if (NS_FAILED(rv))        return rv;      spec = escaped;    }  }  return aBaseURI->Resolve(spec.get(), aResult);}