From c764561eb66dadf766cf4d06cfb9210ccdc8cd38 Mon Sep 17 00:00:00 2001 From: "alecf%netscape.com" Date: Wed, 19 Dec 2001 00:55:42 +0000 Subject: [PATCH] bug 100212 - add new APIs to nsIOService to do URL parsing/conversion of nsIFiles r=dougt, sr=darin --- netwerk/base/public/nsIIOService.idl | 21 +++ netwerk/base/public/nsNetUtil.h | 28 ++++ netwerk/base/src/makefile.win | 1 + netwerk/base/src/nsIOService.h | 5 + netwerk/base/src/nsIOServiceMac.cpp | 157 +++++++++++++++++++++ netwerk/base/src/nsIOServiceOS2.cpp | 200 +++++++++++++++++++++++++++ netwerk/base/src/nsIOServiceUnix.cpp | 118 ++++++++++++++++ netwerk/base/src/nsIOServiceWin.cpp | 154 +++++++++++++++++++++ netwerk/macbuild/netwerk.xml | 54 ++++++++ 9 files changed, 738 insertions(+) create mode 100644 netwerk/base/src/nsIOServiceMac.cpp create mode 100644 netwerk/base/src/nsIOServiceOS2.cpp create mode 100644 netwerk/base/src/nsIOServiceUnix.cpp create mode 100644 netwerk/base/src/nsIOServiceWin.cpp diff --git a/netwerk/base/public/nsIIOService.idl b/netwerk/base/public/nsIIOService.idl index dd67be1e321..7c60c9c51e6 100644 --- a/netwerk/base/public/nsIIOService.idl +++ b/netwerk/base/public/nsIIOService.idl @@ -209,4 +209,25 @@ interface nsIIOService : nsISupports */ string resolveRelativePath(in string relativePath, in string basePath); + + /** + * conversions between nsILocalFile and a file url string + */ + + /** + * getURLSpecFromFile + * gets a file:// url out of an nsIFile + * @param file the file to extract the path from + * @return a file:// style url string + */ + string getURLSpecFromFile(in nsIFile file); + + /** + * initFileFromURL + * Sets the native path of the file given the url string + * @param file the file to initialize with the given spec + * @param url the url string which will be used to initialize the file + * + */ + void initFileFromURLSpec(in nsIFile file, in string url); }; diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index a13a90547a7..6ff1eda4e37 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -702,4 +702,32 @@ NS_NewProxyInfo(const char* type, const char* host, PRInt32 port, nsIProxyInfo* return pps->NewProxyInfo(type, host, port, result); } +inline nsresult +NS_InitFileFromURLSpec(nsIFile* aFile, const char *inURL, + nsIIOService *ioService=nsnull) +{ + nsCOMPtr serv; + if (ioService == nsnull) { + nsresult rv; + serv = do_GetIOService(&rv); + if (NS_FAILED(rv)) return rv; + ioService = serv.get(); + } + return ioService->InitFileFromURLSpec(aFile, inURL); +} + +inline nsresult +NS_GetURLSpecFromFile(nsIFile* aFile, char **aUrl, + nsIIOService *ioService=nsnull) +{ + nsCOMPtr serv; + if (ioService == nsnull) { + nsresult rv; + serv = do_GetIOService(&rv); + if (NS_FAILED(rv)) return rv; + ioService = serv.get(); + } + return ioService->GetURLSpecFromFile(aFile, aUrl); +} + #endif // nsNetUtil_h__ diff --git a/netwerk/base/src/makefile.win b/netwerk/base/src/makefile.win index 2c06518428c..5d1018e6fc7 100644 --- a/netwerk/base/src/makefile.win +++ b/netwerk/base/src/makefile.win @@ -40,6 +40,7 @@ CPP_OBJS = \ .\$(OBJDIR)\nsFileStreams.obj \ .\$(OBJDIR)\nsBufferedStreams.obj \ .\$(OBJDIR)\nsIOService.obj \ + .\$(OBJDIR)\nsIOServiceWin.obj \ .\$(OBJDIR)\nsSocketTransport.obj \ .\$(OBJDIR)\nsSocketTransportService.obj \ .\$(OBJDIR)\nsFileTransport.obj \ diff --git a/netwerk/base/src/nsIOService.h b/netwerk/base/src/nsIOService.h index 79477c73941..9a63b808bd5 100644 --- a/netwerk/base/src/nsIOService.h +++ b/netwerk/base/src/nsIOService.h @@ -103,6 +103,11 @@ protected: void GetPrefBranch(nsIPrefBranch **); void ParsePortList(nsIPrefBranch *prefBranch, const char *pref, PRBool remove); + nsresult ParseFileURL(const char* inURL, + char **outHost, + char **outDirectory, + char **outFileBaseName, + char **outFileExtension); protected: PRPackedBool mOffline; PRPackedBool mOfflineForProfileChange; diff --git a/netwerk/base/src/nsIOServiceMac.cpp b/netwerk/base/src/nsIOServiceMac.cpp new file mode 100644 index 00000000000..06d68790de3 --- /dev/null +++ b/netwerk/base/src/nsIOServiceMac.cpp @@ -0,0 +1,157 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIOService.h" +#include "nsEscape.h" + +static void SwapSlashColon(char * s) +{ + while (*s){ + if (*s == '/') + *s++ = ':'; + else if (*s == ':') + *s++ = '/'; + else + *s++; + } +} + +static void PascalStringCopy(Str255 dst, const char* src) +{ + int srcLength = strlen(src); + NS_ASSERTION(srcLength <= 255, "Oops, Str255 can't hold >255 chars"); + if (srcLength > 255) + srcLength = 255; + dst[0] = srcLength; + memcpy(&dst[1], src, srcLength); +} + + +NS_IMETHODIMP nsIOService::GetURLSpecFromFile(nsIFile* aFile, char * *aURL) +{ + NS_ENSURE_ARG_POINTER(aURL); + *aURL = nsnull; + + nsresult rv; + char* ePath = nsnull; + nsCAutoString escPath; + + rv = aFile->GetPath(&ePath); + if (NS_SUCCEEDED(rv)) { + + SwapSlashColon(ePath); + + // Escape the path with the directory mask + rv = nsStdEscape(ePath, esc_Directory+esc_Forced, escPath); + if (NS_SUCCEEDED(rv)) { + + escPath.Insert("file:///", 0); + + PRBool dir; + rv = aFile->IsDirectory(&dir); + NS_ASSERTION(NS_SUCCEEDED(rv), "Cannot tell if this is a directory"); + if (NS_SUCCEEDED(rv) && dir && escPath[escPath.Length() - 1] != '/') { + // make sure we have a trailing slash + escPath += "/"; + } + *aURL = ToNewCString(escPath); + rv = *aURL ? NS_OK : NS_ERROR_OUT_OF_MEMORY; + } + } + CRTFREEIF(ePath); + return rv; +} + +NS_IMETHODIMP nsIOService::InitFileFromURLSpec(nsIFile* aFile, const char * aURL) +{ + NS_ENSURE_ARG(aURL); + nsresult rv; + + nsXPIDLCString host, directory, fileBaseName, fileExtension; + + nsCOMPtr localFile = do_QueryInterface(aFile, &rv); + NS_ASSERTION(NS_SUCCEEDED(rv), "Only nsILocalFile supported right now"); + if (NS_FAILED(rv)) return rv; + + rv = ParseFileURL(aURL, getter_Copies(host), getter_Copies(directory), + getter_Copies(fileBaseName), getter_Copies(fileExtension)); + if (NS_FAILED(rv)) return rv; + + nsCAutoString path; + nsCAutoString component; + + if (host) + { + // We can end up with a host when given: file:// instead of file:/// + // Check to see if the host is a volume name - If so prepend it + Str255 volName; + FSSpec volSpec; + + PascalStringCopy(volName, host); + volName[++volName[0]] = ':'; + if (::FSMakeFSSpec(0, 0, volName, &volSpec) == noErr) + path += host; + } + if (directory) + { + nsStdEscape(directory, esc_Directory, component); + path += component; + SwapSlashColon((char*)path.get()); + } + if (fileBaseName) + { + nsStdEscape(fileBaseName, esc_FileBaseName, component); + path += component; + } + if (fileExtension) + { + nsStdEscape(fileExtension, esc_FileExtension, component); + path += '.'; + path += component; + } + + nsUnescape((char*)path.get()); + + // wack off leading :'s + if (path.CharAt(0) == ':') + path.Cut(0, 1); + + rv = localFile->InitWithPath(path.get()); + + return rv; + +} diff --git a/netwerk/base/src/nsIOServiceOS2.cpp b/netwerk/base/src/nsIOServiceOS2.cpp new file mode 100644 index 00000000000..cc7f86a723c --- /dev/null +++ b/netwerk/base/src/nsIOServiceOS2.cpp @@ -0,0 +1,200 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Alec Flett + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* OS/2-specific local file uri parsing */ + +#include "nsIOService.h" +#include "nsEscape.h" +//#define INCL_DOSFILEMGR +//#define INCL_DOSERRORS +//#define INCL_DOSPROCESS +//#define INCL_DOSSESMGR +//#define INCL_DOSMODULEMGR +//#define INCL_DOSNLS +//#define INCL_WINCOUNTRY +//#define INCL_WINWORKPLACE +#include + +static int isleadbyte(int c); + +NS_IMETHODIMP +nsIOService::GetURLFromFile(nsIFile *aFile, char * *aURL) +{ + NS_ENSURE_ARG_POINTER(aURL); + *aURL = nsnull; + + nsresult rv; + char* ePath = nsnull; + nsCAutoString escPath; + + rv = aFile->GetPath(&ePath); + if (NS_SUCCEEDED(rv)) { + + // Replace \ with / to convert to an url + char* s = ePath; + while (*s) + { + // We need to call isleadbyte because + // Japanese windows can have 0x5C in the sencond byte + // of a Japanese character, for example 0x8F 0x5C is + // one Japanese character + if(isleadbyte(*s) && *(s+1) != nsnull) { + s++; + } + else if (*s == '\\') + *s = '/'; + s++; + } + + // Escape the path with the directory mask + rv = nsStdEscape(ePath, esc_Directory+esc_Forced, escPath); + if (NS_SUCCEEDED(rv)) { + + escPath.Insert("file:///", 0); + + PRBool dir; + rv = aFile->IsDirectory(&dir); + NS_ASSERTION(NS_SUCCEEDED(rv), "Cannot tell if this is a directory"); + if (NS_SUCCEEDED(rv) && dir && escPath[escPath.Length() - 1] != '/') { + // make sure we have a trailing slash + escPath += "/"; + } + *aURL = ToNewCString(escPath); + rv = *aURL ? NS_OK : NS_ERROR_OUT_OF_MEMORY; + } + } + CRTFREEIF(ePath); + return rv; + +} + +NS_IMETHODIMP +nsIOService::SetFileFromURL(nsIFile *aFile, const char * aURL) +{ + NS_ENSURE_ARG(aURL); + nsresult rv; + + nsCOMPtr localFile = do_QueryInterface(aFile, &rv); + NS_ASSERTION(NS_SUCCEEDED(rv), "Only nsILocalFile supported right now"); + if (NS_FAILED(rv)) return rv; + + nsXPIDLCString host, directory, fileBaseName, fileExtension; + + rv = ParseFileURL(aURL, getter_Copies(host), getter_Copies(directory), + getter_Copies(fileBaseName), getter_Copies(fileExtension)); + if (NS_FAILED(rv)) return rv; + + nsCAutoString path; + nsCAutoString component; + + if (host) + { + // We can end up with a host when given: file://C|/ instead of file:/// + if (strlen((const char *)host) == 2 && ((const char *)host)[1] == '|') + { + path += host; + path.SetCharAt(':', 1); + } + } + if (directory) + { + nsStdEscape(directory, esc_Directory, component); + if (!host && component.Length() > 2 && component.CharAt(2) == '|') + component.SetCharAt(':', 2); + component.ReplaceChar('/', '\\'); + path += component; + } + if (fileBaseName) + { + nsStdEscape(fileBaseName, esc_FileBaseName, component); + path += component; + } + if (fileExtension) + { + nsStdEscape(fileExtension, esc_FileExtension, component); + path += '.'; + path += component; + } + + nsUnescape((char*)path.get()); + + // remove leading '\' + if (path.CharAt(0) == '\\') + path.Cut(0, 1); + + rv = localFile->InitWithPath(path.get()); + + return rv; +} + +static int isleadbyte(int c) +{ + static BOOL bDBCSFilled=FALSE; + static BYTE DBCSInfo[12] = { 0 }; /* According to the Control Program Guide&Ref, + 12 bytes is sufficient */ + BYTE *curr; + BOOL retval = FALSE; + + if( !bDBCSFilled ) { + COUNTRYCODE ctrycodeInfo = { 0 }; + APIRET rc = NO_ERROR; + ctrycodeInfo.country = 0; /* Current Country */ + ctrycodeInfo.codepage = 0; /* Current Codepage */ + + rc = DosQueryDBCSEnv( sizeof( DBCSInfo ), + &ctrycodeInfo, + DBCSInfo ); + if( rc != NO_ERROR ) { + /* we had an error, do something? */ + return FALSE; + } + bDBCSFilled=TRUE; + } + + curr = DBCSInfo; + /* DBCSInfo returned by DosQueryDBCSEnv is terminated with two '0' bytes in a row */ + while(( *curr != 0 ) && ( *(curr+1) != 0)) { + if(( c >= *curr ) && ( c <= *(curr+1) )) { + retval=TRUE; + break; + } + curr+=2; + } + + return retval; +} diff --git a/netwerk/base/src/nsIOServiceUnix.cpp b/netwerk/base/src/nsIOServiceUnix.cpp new file mode 100644 index 00000000000..88f5f18517f --- /dev/null +++ b/netwerk/base/src/nsIOServiceUnix.cpp @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Alec Flett + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Windows-specific local file uri parsing */ +#include "nsIOService.h" +#include "nsEscape.h" + +NS_IMETHODIMP nsIOService::GetURLFromFile(nsIFile *aFile, char * *aURL) +{ + NS_ENSURE_ARG_POINTER(aURL); + *aURL = nsnull; + + nsresult rv; + char* ePath = nsnull; + nsCAutoString escPath; + + rv = aFile->GetPath(&ePath); + if (NS_SUCCEEDED(rv)) { + + // Escape the path with the directory mask + rv = nsStdEscape(ePath, esc_Directory+esc_Forced, escPath); + if (NS_SUCCEEDED(rv)) { + + escPath.Insert("file://", 0); + + PRBool dir; + rv = aFile->IsDirectory(&dir); + NS_ASSERTION(NS_SUCCEEDED(rv), "Cannot tell if this is a directory"); + if (NS_SUCCEEDED(rv) && dir && escPath[escPath.Length() - 1] != '/') { + // make sure we have a trailing slash + escPath += "/"; + } + *aURL = ToNewCString(escPath); + rv = *aURL ? NS_OK : NS_ERROR_OUT_OF_MEMORY; + } + } + CRTFREEIF(ePath); + return rv; +} + +NS_IMETHODIMP nsIOService::SetFileFromURL(nsIFile* aFile, const char * aURL) +{ + NS_ENSURE_ARG(aURL); + nsresult rv; + + nsCOMPtr localFile = do_QueryInterface(aFile, &rv); + NS_ASSERTION(NS_SUCCEEDED(rv), "Only nsILocalFile supported right now"); + if (NS_FAILED(rv)) return rv; + + nsXPIDLCString host, directory, fileBaseName, fileExtension; + + rv = ParseFileURL(aURL, getter_Copies(host), + getter_Copies(directory), + getter_Copies(fileBaseName), + getter_Copies(fileExtension)); + + if (NS_FAILED(rv)) return rv; + + nsCAutoString path; + nsCAutoString component; + + if (directory) { + nsStdEscape(directory, esc_Directory, component); + path += component; + } + if (fileBaseName) + { + nsStdEscape(fileBaseName, esc_FileBaseName, component); + path += component; + } + if (fileExtension) + { + nsStdEscape(fileExtension, esc_FileExtension, component); + path += '.'; + path += component; + } + + nsUnescape((char*)path.get()); + + rv = localFile->InitWithPath(path.get()); + + return rv; +} diff --git a/netwerk/base/src/nsIOServiceWin.cpp b/netwerk/base/src/nsIOServiceWin.cpp new file mode 100644 index 00000000000..d6ded9edfff --- /dev/null +++ b/netwerk/base/src/nsIOServiceWin.cpp @@ -0,0 +1,154 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Alec Flett + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Windows-specific local file uri parsing */ + +#include "nsIOService.h" +#include "nsEscape.h" +#include + +NS_IMETHODIMP +nsIOService::GetURLFromFile(nsIFile *aFile, char * *aURL) +{ + NS_ENSURE_ARG_POINTER(aURL); + *aURL = nsnull; + + nsresult rv; + char* ePath = nsnull; + nsCAutoString escPath; + + rv = aFile->GetPath(&ePath); + if (NS_SUCCEEDED(rv)) { + + // Replace \ with / to convert to an url + char* s = ePath; + while (*s) + { + // We need to call IsDBCSLeadByte because + // Japanese windows can have 0x5C in the sencond byte + // of a Japanese character, for example 0x8F 0x5C is + // one Japanese character + if(::IsDBCSLeadByte(*s) && *(s+1) != nsnull) { + s++; + } + else if (*s == '\\') + *s = '/'; + + s++; + } + + // Escape the path with the directory mask + rv = nsStdEscape(ePath, esc_Directory+esc_Forced, escPath); + if (NS_SUCCEEDED(rv)) { + + escPath.Insert("file:///", 0); + + PRBool dir; + rv = aFile->IsDirectory(&dir); + NS_ASSERTION(NS_SUCCEEDED(rv), "Cannot tell if this is a directory"); + if (NS_SUCCEEDED(rv) && dir && escPath[escPath.Length() - 1] != '/') { + // make sure we have a trailing slash + escPath += "/"; + } + *aURL = ToNewCString(escPath); + rv = *aURL ? NS_OK : NS_ERROR_OUT_OF_MEMORY; + } + } + CRTFREEIF(ePath); + return rv; + +} + +NS_IMETHODIMP +nsIOService::SetFileFromURL(nsIFile *aFile, const char * aURL) +{ + NS_ENSURE_ARG(aURL); + nsresult rv; + + nsCOMPtr localFile = do_QueryInterface(aFile, &rv); + NS_ASSERTION(NS_SUCCEEDED(rv), "Only nsILocalFile supported right now"); + if (NS_FAILED(rv)) return rv; + + nsXPIDLCString host, directory, fileBaseName, fileExtension; + + rv = ParseFileURL(aURL, getter_Copies(host), getter_Copies(directory), + getter_Copies(fileBaseName), getter_Copies(fileExtension)); + if (NS_FAILED(rv)) return rv; + + nsCAutoString path; + nsCAutoString component; + + if (host) + { + // We can end up with a host when given: file://C|/ instead of file:/// + if (strlen((const char *)host) == 2 && ((const char *)host)[1] == '|') + { + path += host; + path.SetCharAt(':', 1); + } + } + if (directory) + { + nsStdEscape(directory, esc_Directory, component); + if (!host && component.Length() > 2 && component.CharAt(2) == '|') + component.SetCharAt(':', 2); + component.ReplaceChar('/', '\\'); + path += component; + } + if (fileBaseName) + { + nsStdEscape(fileBaseName, esc_FileBaseName, component); + path += component; + } + if (fileExtension) + { + nsStdEscape(fileExtension, esc_FileExtension, component); + path += '.'; + path += component; + } + + nsUnescape((char*)path.get()); + + // remove leading '\' + if (path.CharAt(0) == '\\') + path.Cut(0, 1); + + rv = localFile->InitWithPath(path.get()); + + return rv; +} diff --git a/netwerk/macbuild/netwerk.xml b/netwerk/macbuild/netwerk.xml index c5052948a77..0cc966ea1a4 100644 --- a/netwerk/macbuild/netwerk.xml +++ b/netwerk/macbuild/netwerk.xml @@ -1583,6 +1583,13 @@ Text Debug + + Name + nsIOServiceMac.cpp + MacOS + Text + Debug + @@ -2025,6 +2032,11 @@ nsHttpDigestAuth.cpp MacOS + + Name + nsIOServiceMac.cpp + MacOS + @@ -3557,6 +3569,13 @@ Text Debug + + Name + nsIOServiceMac.cpp + MacOS + Text + Debug + @@ -3999,6 +4018,11 @@ nsHttpDigestAuth.cpp MacOS + + Name + nsIOServiceMac.cpp + MacOS + @@ -5517,6 +5541,13 @@ Text Debug + + Name + nsIOServiceMac.cpp + MacOS + Text + Debug + @@ -5949,6 +5980,11 @@ nsHttpDigestAuth.cpp MacOS + + Name + nsIOServiceMac.cpp + MacOS + @@ -7467,6 +7503,13 @@ Text Debug + + Name + nsIOServiceMac.cpp + MacOS + Text + Debug + @@ -7899,6 +7942,11 @@ nsHttpDigestAuth.cpp MacOS + + Name + nsIOServiceMac.cpp + MacOS + @@ -7960,6 +8008,12 @@ nsInputStreamChannel.cpp MacOS + + Necko.shlb + Name + nsIOServiceMac.cpp + MacOS + Necko.shlb Name