nsresult
sbNewFileURI(nsIFile* aFile,
             nsIURI** aURI)
{
  NS_ENSURE_ARG_POINTER(aFile);
  NS_ENSURE_ARG_POINTER(aURI);

  nsresult rv;

  // Get the IO service.
  nsCOMPtr<nsIIOService> ioService = GetIOService(rv);
  NS_ENSURE_SUCCESS(rv, rv);

  // Note that NewFileURI is broken on Linux when dealing with
  // file names not in the filesystem charset; see bug 6227
#if XP_UNIX && !XP_MACOSX
  nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(aFile, &rv);
  if (NS_SUCCEEDED(rv)) {
    // Use the local file persistent descriptor to form a URI spec.
    nsCAutoString descriptor;
    rv = localFile->GetPersistentDescriptor(descriptor);
    if (NS_SUCCEEDED(rv)) {
      // Escape the descriptor into a spec.
      nsCOMPtr<nsINetUtil> netUtil =
        do_CreateInstance("@mozilla.org/network/util;1", &rv);
      NS_ENSURE_SUCCESS(rv, rv);
      nsCAutoString spec;
      rv = netUtil->EscapeString(descriptor,
                                 nsINetUtil::ESCAPE_URL_PATH,
                                 spec);
      NS_ENSURE_SUCCESS(rv, rv);

      // Add the "file:" scheme.
      spec.Insert("file://", 0);

      // Create the URI.
      rv = SB_NewURI(aURI, spec);
      NS_ENSURE_SUCCESS(rv, rv);

      return NS_OK;
    }
  }
#endif

  // Get a URI directly from the file.
  nsCOMPtr<nsIURI> uri;
  rv = ioService->NewFileURI(aFile, getter_AddRefs(uri));
  NS_ENSURE_SUCCESS(rv, rv);

  // Get a main thread URI.
  nsCOMPtr<nsIURI> mainThreadURI = do_MainThreadQueryInterface(uri, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  // Return results.
  mainThreadURI.forget(aURI);

  return NS_OK;
}
nsresult sbDeviceXMLInfo::Read(const char* aDeviceXMLInfoSpecList,
                               const char* aExtensionsList)
{
  NS_ENSURE_ARG_POINTER(aDeviceXMLInfoSpecList);

  nsresult rv;

  Log("URI list:\n%s", aDeviceXMLInfoSpecList);

  // aDeviceXMLInfoSpecList is a space-delimited list of URI strings.
  // Split it out into an array:
  nsTArray<nsCString> uris;
  nsCString_Split(nsDependentCString(aDeviceXMLInfoSpecList),
                  NS_LITERAL_CSTRING(" "),
                  uris);

  if (!aExtensionsList) {
    aExtensionsList = "";
  }

  // Iterate over the strings and convert each one to a URI to
  // load device XML info from:
  const PRUint32 COUNT = uris.Length();
  for (PRUint32 i = 0; i < COUNT; i++) {
    const nsCString & uriStr = uris[i];

    // Skip empty strings:
    if (uriStr.IsEmpty()) {
      continue;
    }

    // Create an nsIURI:
    nsCOMPtr<nsIURI> uri;
    rv = SB_NewURI(getter_AddRefs(uri), uriStr);
    LogIfFailed(rv, "Invalid URI\n%s", uriStr.get());
    NS_ENSURE_SUCCESS(rv, rv);

    // Scan the specified file or directory:
    rv = Read(uri, NS_ConvertUTF8toUTF16(nsDependentCString(aExtensionsList)));
    LogIfFailed(rv, "while reading device info from\n%s", uriStr.get());
    NS_ENSURE_SUCCESS(rv, rv);
  }

  return NS_OK;
}