gecko-dev/netwerk/base/src/nsStdURL.cpp

1141 lines
32 KiB
C++
Raw Normal View History

1999-07-27 08:46:27 +00:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
1999-07-10 05:00:23 +00:00
*
* 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/
1999-07-10 05:00:23 +00:00
*
* 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.
1999-07-10 05:00:23 +00:00
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
1999-07-10 05:00:23 +00:00
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author: Gagan Saksena <gagan@netscape.com>
*
* Contributor(s):
1999-07-10 05:00:23 +00:00
*/
#include "nsIIOService.h"
#include "nsURLHelper.h"
1999-07-10 05:00:23 +00:00
#include "nsStdURL.h"
#include "nsStdURLParser.h"
1999-07-10 05:00:23 +00:00
#include "nscore.h"
#include "nsCRT.h"
#include "nsString.h"
#include "prmem.h"
#include "prprf.h"
#include "nsXPIDLString.h"
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
2000-01-24 21:28:28 +00:00
#include "nsILocalFile.h"
#include "nsEscape.h"
1999-07-10 05:00:23 +00:00
#if defined(XP_PC) && !defined(XP_OS2)
#include <windows.h>
#endif
1999-07-10 05:00:23 +00:00
static NS_DEFINE_CID(kStdURLCID, NS_STANDARDURL_CID);
static NS_DEFINE_CID(kThisStdURLImplementationCID,
NS_THIS_STANDARDURL_IMPLEMENTATION_CID);
static NS_DEFINE_CID(kStdURLParserCID, NS_STANDARDURLPARSER_CID);
static NS_DEFINE_CID(kAuthURLParserCID, NS_AUTHORITYURLPARSER_CID);
static NS_DEFINE_CID(kNoAuthURLParserCID, NS_NOAUTHORITYURLPARSER_CID);
// Global objects. Released from the module shudown routine.
nsIURLParser * nsStdURL::gStdURLParser = NULL;
nsIURLParser * nsStdURL::gAuthURLParser = NULL;
nsIURLParser * nsStdURL::gNoAuthURLParser = NULL;
1999-07-10 05:00:23 +00:00
#if defined (XP_MAC)
2000-05-06 09:07:31 +00:00
static void SwapSlashColon(char * s)
{
while (*s)
{
if (*s == '/')
*s++ = ':';
else if (*s == ':')
*s++ = '/';
else
*s++;
}
}
#endif
NS_IMETHODIMP
nsStdURL::InitGlobalObjects()
2000-01-14 22:01:56 +00:00
{
nsresult rv;
if (!gStdURLParser) {
nsCOMPtr<nsIURLParser> urlParser;
// Get the global instance of standard URLParser
urlParser = do_GetService(kStdURLParserCID, &rv);
if (NS_FAILED(rv)) return rv;
gStdURLParser = urlParser.get();
NS_ADDREF(gStdURLParser);
// Get the global instance of Auth URLParser
urlParser = do_GetService(kAuthURLParserCID, &rv);
if (NS_FAILED(rv)) return rv;
gAuthURLParser = urlParser.get();
NS_ADDREF(gAuthURLParser);
// Get the global instance of NoAuth URLParser
urlParser = do_GetService(kNoAuthURLParserCID, &rv);
if (NS_FAILED(rv)) return rv;
gNoAuthURLParser = urlParser.get();
NS_ADDREF(gNoAuthURLParser);
}
return NS_OK;
}
2000-01-14 22:01:56 +00:00
NS_IMETHODIMP
nsStdURL::ShutdownGlobalObjects()
{
NS_IF_RELEASE(gNoAuthURLParser);
NS_IF_RELEASE(gAuthURLParser);
NS_IF_RELEASE(gStdURLParser);
return NS_OK;
1999-09-21 22:27:06 +00:00
}
nsStdURL::nsStdURL(nsISupports* outer)
1999-07-10 05:00:23 +00:00
: mScheme(nsnull),
mUsername(nsnull),
mPassword(nsnull),
1999-07-10 05:00:23 +00:00
mHost(nsnull),
mPort(-1),
1999-08-27 12:38:06 +00:00
mDirectory(nsnull),
mFileBaseName(nsnull),
mFileExtension(nsnull),
1999-08-27 12:38:06 +00:00
mParam(nsnull),
1999-07-10 05:00:23 +00:00
mQuery(nsnull),
mRef(nsnull),
mDefaultPort(-1),
mSchemeType(nsIURI::UNKNOWN)
1999-07-10 05:00:23 +00:00
{
NS_INIT_AGGREGATED(outer);
InitGlobalObjects();
mURLParser = gStdURLParser; // XXX hack - shouldn't be needed, should be calling Init
}
NS_IMETHODIMP
nsStdURL::Init(PRUint32 urlType, PRInt32 defaultPort,
const char* initialSpec, nsIURI* baseURI)
{
nsresult rv;
switch (urlType) {
case nsIStandardURL::URLTYPE_STANDARD:
mURLParser = gStdURLParser;
break;
case nsIStandardURL::URLTYPE_AUTHORITY:
mURLParser = gAuthURLParser;
break;
case nsIStandardURL::URLTYPE_NO_AUTHORITY:
mURLParser = gNoAuthURLParser;
break;
default:
NS_NOTREACHED("bad urlType");
return NS_ERROR_FAILURE;
}
mDefaultPort = defaultPort;
if (initialSpec == nsnull) return NS_OK;
nsXPIDLCString resolvedURI;
if (baseURI) {
rv = baseURI->Resolve(initialSpec, getter_Copies(resolvedURI));
if (NS_FAILED(rv)) return rv;
}
else {
resolvedURI = initialSpec;
}
return SetSpec(resolvedURI);
1999-07-10 05:00:23 +00:00
}
nsStdURL::nsStdURL(const nsStdURL& otherURL)
: mPort(otherURL.mPort)
{
NS_INIT_REFCNT();
mScheme = otherURL.mScheme ? nsCRT::strdup(otherURL.mScheme) : nsnull;
mUsername = otherURL.mUsername ? nsCRT::strdup(otherURL.mUsername) : nsnull;
mPassword = otherURL.mPassword ? nsCRT::strdup(otherURL.mPassword) : nsnull;
mHost = otherURL.mHost ? nsCRT::strdup(otherURL.mHost) : nsnull;
mDirectory = otherURL.mDirectory ? nsCRT::strdup(otherURL.mDirectory) : nsnull;
mFileBaseName = otherURL.mFileBaseName ? nsCRT::strdup(otherURL.mFileBaseName) : nsnull;
mFileExtension = otherURL.mFileExtension ? nsCRT::strdup(otherURL.mFileExtension) : nsnull;
1999-08-27 12:38:06 +00:00
mParam = otherURL.mParam ? nsCRT::strdup(otherURL.mParam) : nsnull;
mQuery = otherURL.mQuery ? nsCRT::strdup(otherURL.mQuery) : nsnull;
mRef= otherURL.mRef ? nsCRT::strdup(otherURL.mRef) : nsnull;
mURLParser = otherURL.mURLParser;
mSchemeType = otherURL.mSchemeType;
NS_INIT_AGGREGATED(nsnull); // Todo! How?
}
1999-08-12 09:59:24 +00:00
nsStdURL&
nsStdURL::operator=(const nsStdURL& otherURL)
{
mScheme = otherURL.mScheme ? nsCRT::strdup(otherURL.mScheme) : nsnull;
mUsername = otherURL.mUsername ? nsCRT::strdup(otherURL.mUsername) : nsnull;
mPassword = otherURL.mPassword ? nsCRT::strdup(otherURL.mPassword) : nsnull;
1999-08-12 09:59:24 +00:00
mHost = otherURL.mHost ? nsCRT::strdup(otherURL.mHost) : nsnull;
mDirectory = otherURL.mDirectory ? nsCRT::strdup(otherURL.mDirectory) : nsnull;
mFileBaseName = otherURL.mFileBaseName ? nsCRT::strdup(otherURL.mFileBaseName) : nsnull;
mFileExtension = otherURL.mFileExtension ? nsCRT::strdup(otherURL.mFileExtension) : nsnull;
1999-08-27 12:38:06 +00:00
mParam = otherURL.mParam ? nsCRT::strdup(otherURL.mParam) : nsnull;
1999-08-12 09:59:24 +00:00
mQuery = otherURL.mQuery ? nsCRT::strdup(otherURL.mQuery) : nsnull;
mRef= otherURL.mRef ? nsCRT::strdup(otherURL.mRef) : nsnull;
mURLParser = otherURL.mURLParser;
mSchemeType = otherURL.mSchemeType;
1999-08-12 09:59:24 +00:00
NS_INIT_AGGREGATED(nsnull); // Todo! How?
1999-08-27 12:38:06 +00:00
return *this;
1999-08-12 09:59:24 +00:00
}
PRBool
nsStdURL::operator==(const nsStdURL& otherURL) const
{
1999-08-27 12:38:06 +00:00
PRBool retValue = PR_FALSE;
((nsStdURL*)(this))->Equals((nsIURI*)&otherURL,&retValue);
return retValue;
1999-08-12 09:59:24 +00:00
}
1999-07-10 05:00:23 +00:00
nsStdURL::~nsStdURL()
{
CRTFREEIF(mScheme);
CRTFREEIF(mUsername);
CRTFREEIF(mPassword);
CRTFREEIF(mHost);
CRTFREEIF(mDirectory);
CRTFREEIF(mFileBaseName);
CRTFREEIF(mFileExtension);
1999-08-27 12:38:06 +00:00
CRTFREEIF(mParam);
CRTFREEIF(mQuery);
CRTFREEIF(mRef);
1999-07-10 05:00:23 +00:00
}
NS_IMPL_AGGREGATED(nsStdURL);
NS_IMETHODIMP
nsStdURL::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_ASSERTION(aInstancePtr, "no instance pointer");
if(!aInstancePtr)
return NS_ERROR_INVALID_POINTER;
if (aIID.Equals(NS_GET_IID(nsISupports)))
*aInstancePtr = GetInner();
else if (aIID.Equals(kThisStdURLImplementationCID) || // used by Equals
aIID.Equals(NS_GET_IID(nsIURL)) ||
aIID.Equals(NS_GET_IID(nsIURI)) ||
aIID.Equals(NS_GET_IID(nsIFileURL)))
1999-07-10 05:00:23 +00:00
*aInstancePtr = NS_STATIC_CAST(nsIURL*, this);
else if (aIID.Equals(NS_GET_IID(nsIStandardURL))) {
*aInstancePtr = NS_STATIC_CAST(nsIStandardURL*, this);
}
else {
*aInstancePtr = nsnull;
return NS_NOINTERFACE;
1999-07-10 05:00:23 +00:00
}
NS_ADDREF((nsISupports*)*aInstancePtr);
return NS_OK;
1999-07-10 05:00:23 +00:00
}
NS_IMETHODIMP
nsStdURL::Equals(nsIURI *i_OtherURI, PRBool *o_Equals)
{
1999-08-27 12:38:06 +00:00
PRBool eq = PR_FALSE;
if (i_OtherURI) {
nsStdURL* other = nsnull;
nsresult rv = i_OtherURI->QueryInterface(kThisStdURLImplementationCID,
(void**)&other);
if (NS_FAILED(rv)) {
*o_Equals = eq;
return rv;
}
// Maybe the directorys are different
if (nsCRT::strcasecmp(mDirectory, other->mDirectory)==0) {
// Or the Filebasename?
if (nsCRT::strcasecmp(mFileBaseName, other->mFileBaseName)==0) {
// Maybe the Fileextension?
if (nsCRT::strcasecmp(mFileExtension, other->mFileExtension)==0) {
// Or the Host?
if (nsCRT::strcasecmp(mHost, other->mHost)==0) {
// Or the Scheme?
if (nsCRT::strcasecmp(mScheme, other->mScheme)==0) {
// Username?
if (nsCRT::strcasecmp(mUsername, other->mUsername)==0) {
// Password?
if (nsCRT::strcasecmp(mPassword, other->mPassword)==0) {
// Param?
if (nsCRT::strcasecmp(mParam, other->mParam)==0) {
// Query?
if (nsCRT::strcasecmp(mQuery, other->mQuery)==0) {
// Ref?
if (nsCRT::strcasecmp(mRef, other->mRef)==0) {
// Port?
PRInt32 myPort = mPort != -1 ? mPort : mDefaultPort;
PRInt32 theirPort = other->mPort != -1 ? other->mPort : other->mDefaultPort;
if (myPort == theirPort) {
// They are equal!!!!!
eq = PR_TRUE;
}
}
}
}
}
}
}
}
}
}
}
NS_RELEASE(other);
1999-08-27 12:38:06 +00:00
}
*o_Equals = eq;
return NS_OK;
1999-07-10 05:00:23 +00:00
}
NS_IMETHODIMP
nsStdURL::SchemeIs(PRUint32 i_Scheme, PRBool *o_Equals)
{
NS_ENSURE_ARG_POINTER(o_Equals);
if (i_Scheme == nsIURI::UNKNOWN)
return NS_ERROR_INVALID_ARG;
*o_Equals = (mSchemeType == i_Scheme);
return NS_OK;
}
1999-07-10 05:00:23 +00:00
NS_IMETHODIMP
nsStdURL::Clone(nsIURI **o_URI)
{
nsStdURL* url = new nsStdURL(*this); /// TODO check outer?
1999-07-10 05:00:23 +00:00
if (url == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
1999-08-27 12:38:06 +00:00
nsresult rv= NS_OK;
1999-07-10 05:00:23 +00:00
*o_URI = url;
NS_ADDREF(url);
return rv;
}
nsresult
nsStdURL::Parse(const char* i_Spec)
{
// Main parser
NS_PRECONDITION( (nsnull != i_Spec), "Parse called on empty url!");
if (!i_Spec)
2000-01-14 22:01:56 +00:00
return NS_ERROR_MALFORMED_URI;
1999-08-27 12:38:06 +00:00
NS_PRECONDITION( (nsnull != mURLParser), "Parse called without parser!");
2000-02-08 05:55:08 +00:00
if (!mURLParser) return NS_ERROR_NULL_POINTER;
// Parse the spec
char* ePath = nsnull;
nsresult rv = mURLParser->ParseAtScheme(i_Spec, &mScheme, &mUsername,
&mPassword, &mHost, &mPort,
&ePath);
if (0 == PL_strcasecmp("about", mScheme))
mSchemeType = nsIURI::ABOUT;
else if (0 == PL_strcasecmp("chrome", mScheme))
mSchemeType = nsIURI::CHROME;
else if (0 == PL_strcasecmp("file", mScheme))
mSchemeType = nsIURI::FILE;
else if (0 == PL_strcasecmp("ftp", mScheme))
mSchemeType = nsIURI::FTP;
else if (0 == PL_strcasecmp("http", mScheme))
mSchemeType = nsIURI::HTTP;
else if (0 == PL_strcasecmp("https", mScheme))
mSchemeType = nsIURI::HTTPS;
else if (0 == PL_strcasecmp("imap", mScheme))
mSchemeType = nsIURI::IMAP;
else if (0 == PL_strcasecmp("jar", mScheme))
mSchemeType = nsIURI::JAR;
else if (0 == PL_strcasecmp("javascript", mScheme))
mSchemeType = nsIURI::JAVASCRIPT;
else if (0 == PL_strcasecmp("mailbox", mScheme))
mSchemeType = nsIURI::MAILBOX;
else if (0 == PL_strcasecmp("mailto", mScheme))
mSchemeType = nsIURI::MAILTO;
else if (0 == PL_strcasecmp("news", mScheme))
mSchemeType = nsIURI::NEWS;
else if (0 == PL_strcasecmp("resource", mScheme))
mSchemeType = nsIURI::RESOURCE;
else
mSchemeType = nsIURI::UNKNOWN;
if (NS_SUCCEEDED(rv)) {
// Now parse the path
rv = mURLParser->ParseAtDirectory(ePath, &mDirectory, &mFileBaseName,
&mFileExtension, &mParam,
&mQuery, &mRef);
}
CRTFREEIF(ePath);
return rv;
}
1999-07-10 05:00:23 +00:00
nsresult
nsStdURL::GetString(char** result, char* fromEscapedStr, Format toFormat)
{
// Given str "foo%20bar", gets "foo bar" if UNESCAPED
nsresult rv = NS_OK;
if (toFormat == UNESCAPED) {
rv = nsURLUnescape(fromEscapedStr, result);
} else
rv = DupString(result, fromEscapedStr);
return rv;
}
2000-01-14 22:01:56 +00:00
nsresult
nsStdURL::AppendString(nsCString& buffer, char * fromUnescapedStr,
Format toFormat, PRInt16 mask)
{
// Given str "foo bar", appends "foo%20bar" to buffer if ESCAPED
nsresult rv = NS_OK;
if (!fromUnescapedStr)
return NS_ERROR_FAILURE;
if (toFormat == HOSTESCAPED && strchr(fromUnescapedStr, ':')) {
buffer += "[";
buffer += fromUnescapedStr;
buffer += "]";
}
else if (toFormat != UNESCAPED) {
rv = nsAppendURLEscapedString(buffer, fromUnescapedStr, mask);
} else {
buffer += fromUnescapedStr;
}
return rv;
}
nsresult
nsStdURL::AppendPreHost(nsCString& buffer, char* i_Username,
char* i_Password, Format toFormat)
{
nsresult rv = NS_OK;
if (i_Username)
{
rv = AppendString(buffer,i_Username,ESCAPED,
nsIIOService::url_Username);
if (NS_FAILED(rv))
return rv;
if (i_Password)
2000-01-14 22:01:56 +00:00
{
buffer += ':';
rv = AppendString(buffer,i_Password,ESCAPED,
nsIIOService::url_Password);
if (NS_FAILED(rv))
return rv;
2000-01-14 22:01:56 +00:00
}
}
return rv;
}
1999-07-10 05:00:23 +00:00
nsresult
nsStdURL::AppendFileName(nsCString& buffer, char* i_FileBaseName,
char* i_FileExtension, Format toFormat)
{
nsresult rv = NS_OK;
if (i_FileBaseName)
{
rv = AppendString(buffer,i_FileBaseName,ESCAPED,
nsIIOService::url_FileBaseName);
if (NS_FAILED(rv))
return rv;
}
if (i_FileExtension)
{
buffer += '.';
rv = AppendString(buffer,i_FileExtension,ESCAPED,
nsIIOService::url_FileExtension);
}
return rv;
}
2000-01-14 22:01:56 +00:00
nsresult
nsStdURL::GetSpec(char **o_Spec)
{
nsresult rv = NS_OK;
nsCAutoString finalSpec; // guaranteed to be singlebyte.
1999-08-27 12:38:06 +00:00
if (mScheme)
{
rv = AppendString(finalSpec,mScheme,ESCAPED,nsIIOService::url_Scheme);
1999-08-27 12:38:06 +00:00
finalSpec += "://";
}
rv = AppendPreHost(finalSpec,mUsername,mPassword,ESCAPED);
if (mUsername)
2000-01-14 22:01:56 +00:00
{
finalSpec += "@";
2000-01-14 22:01:56 +00:00
}
1999-08-27 12:38:06 +00:00
if (mHost)
{
rv = AppendString(finalSpec,mHost,HOSTESCAPED,nsIIOService::url_Host);
if (-1 != mPort && mPort != mDefaultPort)
{
char* portBuffer = PR_smprintf(":%d", mPort);
if (!portBuffer)
return NS_ERROR_OUT_OF_MEMORY;
finalSpec += portBuffer;
PR_smprintf_free(portBuffer);
portBuffer = 0;
}
1999-08-27 12:38:06 +00:00
}
char* ePath = nsnull;
rv = GetPath(&ePath);
if NS_FAILED(rv) {
CRTFREEIF(ePath);
return rv;
}
if (ePath)
1999-08-27 12:38:06 +00:00
{
finalSpec += ePath;
1999-08-27 12:38:06 +00:00
}
*o_Spec = finalSpec.ToNewCString();
CRTFREEIF(ePath);
return (*o_Spec ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
1999-07-10 05:00:23 +00:00
}
nsresult
nsStdURL::GetPrePath(char **o_Spec)
{
nsresult rv = NS_OK;
nsCAutoString finalSpec; // guaranteed to be singlebyte.
if (mScheme)
{
rv = AppendString(finalSpec,mScheme,ESCAPED,nsIIOService::url_Scheme);
finalSpec += "://";
}
rv = AppendPreHost(finalSpec,mUsername,mPassword,ESCAPED);
if (mUsername)
{
finalSpec += "@";
}
if (mHost)
{
rv = AppendString(finalSpec,mHost,HOSTESCAPED,nsIIOService::url_Host);
if (-1 != mPort)
{
char* portBuffer = PR_smprintf(":%d", mPort);
if (!portBuffer)
return NS_ERROR_OUT_OF_MEMORY;
finalSpec += portBuffer;
PR_smprintf_free(portBuffer);
portBuffer = 0;
}
}
*o_Spec = finalSpec.ToNewCString();
return (*o_Spec ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
}
nsresult
nsStdURL::SetPrePath(const char *i_Spec)
{
NS_NOTREACHED("nsStdURL::SetPrePath");
return NS_ERROR_NOT_IMPLEMENTED;
}
1999-07-10 05:00:23 +00:00
NS_METHOD
nsStdURL::Create(nsISupports *aOuter,
1999-08-27 12:38:06 +00:00
REFNSIID aIID,
void **aResult)
1999-07-10 05:00:23 +00:00
{
if (!aResult)
1999-08-27 12:38:06 +00:00
return NS_ERROR_INVALID_POINTER;
if (aOuter && !aIID.Equals(NS_GET_IID(nsISupports)))
return NS_ERROR_INVALID_ARG;
nsStdURL* url = new nsStdURL(aOuter);
1999-07-10 05:00:23 +00:00
if (url == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = url->AggregatedQueryInterface(aIID, aResult);
if (NS_FAILED(rv)) {
delete url;
return rv;
}
1999-07-10 05:00:23 +00:00
return rv;
2000-01-14 22:01:56 +00:00
}
NS_METHOD
nsStdURL::GetPreHost(char **o_PreHost)
2000-01-14 22:01:56 +00:00
{
if (!o_PreHost)
2000-01-14 22:01:56 +00:00
return NS_ERROR_NULL_POINTER;
if (!mUsername) {
*o_PreHost = nsnull;
} else {
nsCAutoString temp;
nsresult rv = AppendPreHost(temp,mUsername,mPassword,ESCAPED);
if (NS_FAILED(rv))
return rv;
*o_PreHost = temp.ToNewCString();
if (!*o_PreHost)
return NS_ERROR_OUT_OF_MEMORY;
2000-01-14 22:01:56 +00:00
}
return NS_OK;
1999-07-10 05:00:23 +00:00
}
NS_IMETHODIMP
nsStdURL::SetDirectory(const char* i_Directory)
1999-07-10 05:00:23 +00:00
{
if (!i_Directory)
return NS_ERROR_NULL_POINTER;
if (mDirectory)
nsCRT::free(mDirectory);
nsCAutoString dir;
if ('/' != *i_Directory)
dir += "/";
dir += i_Directory;
// if the last slash is missing then attach it
if (dir.Last() != '/') {
dir += "/";
}
CRTFREEIF(mDirectory);
-Fixed parsing to handle the mscott cases of- mailbox://foo:25/user@netscape.com pop3://foo:110?check -Fixed missing directory situations. (thanks Andreas) -Removed the temporary hack for converting from ToNewCString to nsCRT::free'able type. This removes the FMM errors on Bruce's log. No more mismatched freeing. ? diffs Index: nsStdURL.cpp =================================================================== RCS file: /cvsroot/mozilla/netwerk/base/src/nsStdURL.cpp,v retrieving revision 1.5 diff -r1.5 nsStdURL.cpp 147,150c147 < { < //TODO < return NS_ERROR_FAILURE; // this should really be NS_ERROR_URL_PARSING < } --- > return NS_ERROR_MALFORMED_URI; 154c151 < static const char delimiters[] = "/:@"; //this order is optimized. --- > static const char delimiters[] = "/:@?"; //this order is optimized. 157,493c154 < if (brk) < { < switch (*brk) < { < case '/' : < // If the URL starts with a slash then everything is a path < if (brk == mSpec) < { < ExtractString(mSpec, &mPath, 0, len); < return NS_OK; < } < else // The first part is host, so its host/path < { < ExtractString(mSpec, &mHost, 0, (brk - mSpec)); < ExtractString(mSpec, &mPath, (brk - mSpec), (len - (brk - mSpec))); < return NS_OK; < } < break; < case ':' : < if (*(brk+1) == '/') < { < ExtractString(mSpec, &mScheme, 0, (brk - mSpec)); < < if (*(brk+2) == '/') // e.g. http:// < // If the first colon is followed by // then its definitely a spec < { < lastbrk = brk+3; < brk = PL_strpbrk(lastbrk, delimiters); < if (brk) < { < switch (*brk) < { < case '/' : // standard case- http://host/path < ExtractString(mSpec, &mHost, < (lastbrk - mSpec), (brk - lastbrk)); < ExtractString(mSpec, &mPath, < (brk - mSpec), (len - (brk - mSpec))); < return NS_OK; < break; < case ':' : < { < // It could be http://user:pass@host/path < // or http://host:port/path < // For the first case, there has to be an < // @ after this colon, so... < char* atSign = PL_strchr(brk, '@'); < if (atSign) < { < ExtractString(mSpec, &mPreHost, < (lastbrk - mSpec), (atSign - lastbrk)); < brk = PL_strpbrk(atSign+1, "/:"); < if (brk) // http://user:pass@host:port/path or http://user:pass@host/path < { < ExtractString(mSpec, &mHost, < (atSign+1 - mSpec), < (brk - (atSign+1))); < if (*brk == '/') < { < ExtractString(mSpec, &mPath, < (brk - mSpec), < len - (brk - mSpec)); < return NS_OK; < } < else // we have a port since (brk == ':') < { < lastbrk = brk+1; < brk = PL_strchr(lastbrk, '/'); < if (brk) // http://user:pass@host:port/path < { < mPort = ExtractPortFrom(mSpec, (lastbrk - mSpec), (brk-lastbrk)); < ExtractString(mSpec, &mPath, (brk-mSpec), len - (brk-mSpec)); < return NS_OK; < } < else // http://user:pass@host:port < { < mPort = ExtractPortFrom(mSpec, (lastbrk - mSpec), len - (lastbrk - mSpec)); < return NS_OK; < } < } < < } < else // its just http://user:pass@host < { < ExtractString(mSpec, &mHost, < (atSign+1 - mSpec), < len - (atSign+1 - mSpec)); < return NS_OK; < } < } < else // definitely the port option, i.e. http://host:port/path < { < ExtractString(mSpec, &mHost, < (lastbrk-mSpec), < (brk-lastbrk)); < lastbrk = brk+1; < brk = PL_strchr(lastbrk, '/'); < if (brk) // http://host:port/path < { < mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk)); < ExtractString(mSpec, &mPath, < (brk-mSpec), < len - (brk-mSpec)); < return NS_OK; < } < else // http://host:port < { < mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),len - (lastbrk-mSpec)); < return NS_OK; < } < } < } < break; < case '@' : < // http://user@host... < { < ExtractString(mSpec, &mPreHost, < (lastbrk-mSpec), (brk-lastbrk)); < lastbrk = brk+1; < brk = PL_strpbrk(lastbrk, ":/"); < if (brk) < { < ExtractString(mSpec, &mHost, < (lastbrk-mSpec), (brk - lastbrk)); < if (*brk == ':') // http://user@host:port... < { < lastbrk = brk+1; < brk = PL_strchr(lastbrk, '/'); < if (brk) // http://user@host:port/path < { < mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk)); < ExtractString(mSpec, &mPath, < (brk-mSpec), < len - (brk-mSpec)); < return NS_OK; < } < else // http://user@host:port < { < mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),len - (lastbrk-mSpec)); < return NS_OK; < } < < } < else // (*brk == '/') so no port just path i.e. http://user@host/path < { < ExtractString(mSpec, &mPath, < (brk - mSpec), < len - (brk - mSpec)); < return NS_OK; < } < } < else // its just http://user@host < { < ExtractString(mSpec, &mHost, < (lastbrk+1 - mSpec), len - (lastbrk+1 - mSpec)); < return NS_OK; < } < < } < break; < default: NS_POSTCONDITION(0, "This just can't be!"); < break; < } < < } < else // everything else is a host, as in http://host < { < ExtractString(mSpec, &mHost, < (lastbrk - mSpec), < len - (lastbrk - mSpec)); < return NS_OK; < } < < } < else // This is a no // path alone case like file:/path, there is never a prehost/host in this case. < { < ExtractString(mSpec, &mPath, (brk-mSpec+1), len - (brk-mSpec+1)); < return NS_OK; < } < } < else // scheme:host or host:port... < { < lastbrk = brk+1; < < if ((*lastbrk >= '0') && (*lastbrk <= '9')) //host:port... < { < ExtractString(mSpec, &mHost, 0, (brk - mSpec)); < brk = PL_strpbrk(lastbrk, delimiters); < if (brk) < { < switch (*brk) < { < case '/' : // The path, so its host:port/path < mPort = ExtractPortFrom(mSpec, lastbrk-mSpec, brk-lastbrk); < ExtractString(mSpec, &mPath, brk- mSpec, len - (brk-mSpec)); < return NS_OK; < break; < case ':' : < return NS_ERROR_FAILURE;//TODO NS_ERROR_URL_PARSING; < break; < case '@' : < // This is a special case of user:pass@host... so < // Cleanout our earliar knowledge of host < ExtractString(mSpec, &mHost, -1, -1); < < ExtractString(mSpec, &mPreHost, 0, (brk-mSpec)); < lastbrk = brk+1; < brk = PL_strpbrk(lastbrk, ":/"); < if (brk) < { < ExtractString(mSpec, &mHost, < (lastbrk-mSpec), (brk-lastbrk)); < if (*brk == ':') // user:pass@host:port... < { < lastbrk = brk+1; < brk = PL_strchr(lastbrk, '/'); < if (brk) // user:pass@host:port/path < { < mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk)); < ExtractString(mSpec, &mPath, < (brk-mSpec), len - (brk-mSpec)); < return NS_OK; < } < else // user:pass@host:port < { < mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),len - (lastbrk-mSpec)); < return NS_OK; < } < } < else // (*brk == '/') so user:pass@host/path < { < ExtractString(mSpec, &mPath, (brk - mSpec), len - (brk - mSpec)); < return NS_OK; < } < } < else // its user:pass@host so everthing else is just the host < { < ExtractString(mSpec, &mHost, < (lastbrk-mSpec), len - (lastbrk-mSpec)); < return NS_OK; < } < < break; < default: NS_POSTCONDITION(0, "This just can't be!"); < break; < } < } < else // Everything else is just the port < { < mPort = ExtractPortFrom(mSpec, lastbrk-mSpec, len - (lastbrk-mSpec)); < return NS_OK; < } < } < else // scheme:host... < { < ExtractString(mSpec, &mScheme, 0, (brk - mSpec)); < brk = PL_strpbrk(lastbrk, delimiters); < if (brk) < { < switch (*brk) < { < case '/' : // The path, so its scheme:host/path < ExtractString(mSpec, &mHost, (lastbrk-mSpec), (brk-lastbrk)); < ExtractString(mSpec, &mPath, (brk - mSpec), len - (brk - mSpec)); < return NS_OK; < break; < case '@' : // scheme:user@host... < ExtractString(mSpec, &mPreHost, (lastbrk-mSpec), (brk-lastbrk)); < // TODO more here... < break; < case ':' : // scheme:user:pass@host... or scheme:host:port... < /* TODO < if you find @ in the remaining string then // scheme:user:pass@host... < { < < < } < else // scheme:host:port < { < ExtractString(mSpec, &mHost, (lastbrk-mSpec), (brk-lastbrk)); < < } < */ < break; < default: NS_POSTCONDITION(0, "This just can't be!"); < break; < } < } < else // its just scheme:host < { < ExtractString(mSpec, &mHost, (lastbrk-mSpec), len - (lastbrk-mSpec)); < return NS_OK; < } < } < } < break; < case '@' : < //Everything before the @ is the prehost stuff < ExtractString(mSpec, &mPreHost, 0, brk-mSpec); < lastbrk = brk+1; < brk = PL_strpbrk(lastbrk, ":/"); < if (brk) < { < ExtractString(mSpec, &mHost, (lastbrk-mSpec), (brk-lastbrk)); < if (*brk == ':') // user@host:port... < { < lastbrk = brk+1; < brk = PL_strchr(lastbrk, '/'); < if (brk) // user@host:port/path < { < mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk)); < ExtractString(mSpec, &mPath, (brk-mSpec), len - (brk-mSpec)); < return NS_OK; < } < else // user@host:port < { < mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),len - (lastbrk-mSpec)); < return NS_OK; < } < } < else // (*brk == '/') so user@host/path < { < ExtractString(mSpec, &mPath, (brk - mSpec), len - (brk - mSpec)); < return NS_OK; < } < } < else // its user@host so everything else is just the host < { < ExtractString(mSpec, &mHost, (lastbrk-mSpec), (len - (lastbrk-mSpec))); < return NS_OK; < } < break; < default: < NS_ASSERTION(0, "This just can't be!"); < break; < } < } < else // everything is a host --- > if (!brk) // everything is a host 495a157 > return NS_OK; 496a159,501 > switch (*brk) > { > case '/' : > case '?' : > // If the URL starts with a slash then everything is a path > if (brk == mSpec) > { > ExtractString(mSpec, &mPath, 0, len); > return NS_OK; > } > else // The first part is host, so its host/path > { > ExtractString(mSpec, &mHost, 0, (brk - mSpec)); > ExtractString(mSpec, &mPath, (brk - mSpec), (len - (brk - mSpec))); > return NS_OK; > } > break; > case ':' : > if (*(brk+1) == '/') > { > ExtractString(mSpec, &mScheme, 0, (brk - mSpec)); > > if (*(brk+2) == '/') // e.g. http:// > // If the first colon is followed by // then its definitely a spec > { > lastbrk = brk+3; > brk = PL_strpbrk(lastbrk, delimiters); > if (!brk) // everything else is a host, as in http://host > { > ExtractString(mSpec, &mHost, > (lastbrk - mSpec), > len - (lastbrk - mSpec)); > return NS_OK; > } > switch (*brk) > { > case '/' : // standard case- http://host/path > case '?' : // missing path cases > ExtractString(mSpec, &mHost, > (lastbrk - mSpec), (brk - lastbrk)); > ExtractString(mSpec, &mPath, > (brk - mSpec), (len - (brk - mSpec))); > return NS_OK; > break; > case ':' : // http://user:... or http://host:... > { > // It could be http://user:pass@host/path > // or http://host:port/path we find that by checking further... > char* nextbrk = PL_strpbrk(brk+1, delimiters); > if (!nextbrk) // http://host:port > { > ExtractString(mSpec, &mHost, > (lastbrk-mSpec), (brk-lastbrk)); > mPort = ExtractPortFrom(mSpec, > (lastbrk-mSpec), len - (lastbrk-mSpec)); > return NS_OK; > } > switch (*nextbrk) > { > case '/': // http://host:port/path > case '?': // http://host:port?path > ExtractString(mSpec, &mHost, > (lastbrk-mSpec), (brk-lastbrk)); > mPort = ExtractPortFrom(mSpec, (brk-mSpec+1),(nextbrk-brk-1)); > ExtractString(mSpec, &mPath, > (nextbrk-mSpec), len - (nextbrk-mSpec)); > return NS_OK; > break; > case '@': // http://user:pass@host... > ExtractString(mSpec, &mPreHost, > (lastbrk - mSpec), (nextbrk - lastbrk)); > brk = PL_strpbrk(nextbrk+1, delimiters); > if (!brk) // its just http://user:pass@host > { > ExtractString(mSpec, &mHost, > (nextbrk+1 - mSpec), > len - (nextbrk+1 - mSpec)); > return NS_OK; > } > > ExtractString(mSpec, &mHost, > (nextbrk+1 - mSpec), brk - (nextbrk+1)); > > switch (*brk) > { > case '/': // http://user:pass@host/path > case '?': > ExtractString(mSpec, &mPath, > (nextbrk+1 - mSpec), > len - (nextbrk+1 - mSpec)); > return NS_OK; > break; > case ':': // http://user:pass@host:port... > lastbrk = brk; > brk = PL_strpbrk(lastbrk+1, "/?"); > if (brk) // http://user:pass@host:port/path > { > mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk)); > ExtractString(mSpec, &mPath, (brk-mSpec), len - (brk-mSpec)); > return NS_OK; > } > else // http://user:pass@host:port > { > mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec), > len - (lastbrk-mSpec)); > return NS_OK; > } > break; > default: NS_POSTCONDITION(0, "This just can't be!"); > break; > } > break; > case ':': // three colons! > return NS_ERROR_MALFORMED_URI; > break; > default: NS_POSTCONDITION(0, "This just can't be!"); > break; > } > } > break; > case '@' : // http://user@host... > { > ExtractString(mSpec, &mPreHost, > (lastbrk-mSpec), (brk-lastbrk)); > lastbrk = brk+1; > brk = PL_strpbrk(lastbrk, delimiters); > if (!brk) // its just http://user@host > { > ExtractString(mSpec, &mHost, > (lastbrk+1 - mSpec), > len - (lastbrk+1 - mSpec)); > return NS_OK; > } > ExtractString(mSpec, &mHost, > (lastbrk-mSpec), (brk - lastbrk)); > switch (*brk) > { > case ':' : // http://user@host:port... > lastbrk = brk+1; > brk = PL_strpbrk(lastbrk, "/?"); > if (brk) // http://user@host:port/path > { > mPort = ExtractPortFrom(mSpec, > (lastbrk-mSpec),(brk-lastbrk)); > ExtractString(mSpec, &mPath, > (brk-mSpec), > len - (brk-mSpec)); > return NS_OK; > } > else // http://user@host:port > { > mPort = ExtractPortFrom(mSpec, > (lastbrk-mSpec), > len - (lastbrk-mSpec)); > return NS_OK; > } > break; > case '/' : // http://user@host/path > case '?' : // http://user@host?path > ExtractString(mSpec, &mPath, > (brk - mSpec), > len - (brk - mSpec)); > return NS_OK; > break; > case '@' : > return NS_ERROR_MALFORMED_URI; > default : NS_POSTCONDITION(0, > "This just can't be!"); > break; > } > } > break; > default: NS_POSTCONDITION(0, "This just can't be!"); > break; > } > } > else // This is a no // path alone case like file:/path, > // there is never a prehost/host in this case. > { > ExtractString(mSpec, &mPath, (brk-mSpec+1), > len - (brk-mSpec+1)); > return NS_OK; > } > } > else // scheme:host or host:port... > { > lastbrk = brk+1; > > if ((*lastbrk >= '0') && (*lastbrk <= '9')) //host:port... > { > ExtractString(mSpec, &mHost, 0, (brk - mSpec)); > brk = PL_strpbrk(lastbrk, delimiters); > if (!brk) // Everything else is just the port > { > mPort = ExtractPortFrom(mSpec, lastbrk-mSpec, > len - (lastbrk-mSpec)); > return NS_OK; > } > switch (*brk) > { > case '/' : // The path, so its host:port/path > case '?' : // The path, so its host:port?path > mPort = ExtractPortFrom(mSpec, lastbrk-mSpec, > brk-lastbrk); > ExtractString(mSpec, &mPath, brk- mSpec, > len - (brk-mSpec)); > return NS_OK; > break; > case ':' : > return NS_ERROR_MALFORMED_URI; > break; > case '@' : > // This is a special case of user:pass@host... so > // Cleanout our earliar knowledge of host > ExtractString(mSpec, &mHost, -1, -1); > > ExtractString(mSpec, &mPreHost, 0, (brk-mSpec)); > lastbrk = brk+1; > brk = PL_strpbrk(lastbrk, ":/"); > // its user:pass@host so everthing else is just the host > if (!brk) > { > ExtractString(mSpec, &mHost, > (lastbrk-mSpec), len - (lastbrk-mSpec)); > return NS_OK; > } > ExtractString(mSpec, &mHost, > (lastbrk-mSpec), (brk-lastbrk)); > if (*brk == ':') // user:pass@host:port... > { > lastbrk = brk+1; > brk = PL_strpbrk(lastbrk, "/?"); > if (brk) // user:pass@host:port/path > { > mPort = ExtractPortFrom(mSpec, > (lastbrk-mSpec),(brk-lastbrk)); > ExtractString(mSpec, &mPath, > (brk-mSpec), len - (brk-mSpec)); > return NS_OK; > } > else // user:pass@host:port > { > mPort = ExtractPortFrom(mSpec, > (lastbrk-mSpec),len - (lastbrk-mSpec)); > return NS_OK; > } > } > else // (*brk == '/') so user:pass@host/path > { > ExtractString(mSpec, &mPath, (brk - mSpec), > len - (brk - mSpec)); > return NS_OK; > } > break; > default: NS_POSTCONDITION(0, "This just can't be!"); > break; > } > } > else // scheme:host... > { > ExtractString(mSpec, &mScheme, 0, (brk - mSpec)); > brk = PL_strpbrk(lastbrk, delimiters); > if (!brk) // its just scheme:host > { > ExtractString(mSpec, &mHost, (lastbrk-mSpec), > len - (lastbrk-mSpec)); > return NS_OK; > } > switch (*brk) > { > case '/' : // The path, so its scheme:host/path > case '?' : // The path, so its scheme:host?path > ExtractString(mSpec, &mHost, (lastbrk-mSpec), > (brk-lastbrk)); > ExtractString(mSpec, &mPath, (brk - mSpec), > len - (brk - mSpec)); > return NS_OK; > break; > case '@' : // scheme:user@host... > ExtractString(mSpec, &mPreHost, (lastbrk-mSpec), > (brk-lastbrk)); > // TODO more here... > break; > case ':' : // scheme:user:pass@host...or scheme:host:port... > /* TODO > if you find @ in the remaining string > then // scheme:user:pass@host... > { > > > } > else // scheme:host:port > { > ExtractString(mSpec, &mHost, (lastbrk-mSpec), > (brk-lastbrk)); > } > */ > break; > default: NS_POSTCONDITION(0, "This just can't be!"); > break; > } > } > } > break; > case '@' : > //Everything before the @ is the prehost stuff > ExtractString(mSpec, &mPreHost, 0, brk-mSpec); > lastbrk = brk+1; > brk = PL_strpbrk(lastbrk, ":/"); > if (!brk) // its user@host so everything else is just the host > { > ExtractString(mSpec, &mHost, (lastbrk-mSpec), > (len - (lastbrk-mSpec))); > return NS_OK; > } > ExtractString(mSpec, &mHost, (lastbrk-mSpec), (brk-lastbrk)); > if (*brk == ':') // user@host:port... > { > lastbrk = brk+1; > brk = PL_strpbrk(lastbrk, "/?"); > if (brk) // user@host:port/path > { > mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk)); > ExtractString(mSpec, &mPath, (brk-mSpec), len - (brk-mSpec)); > return NS_OK; > } > else // user@host:port > { > mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec), > len - (lastbrk-mSpec)); > return NS_OK; > } > } > else // (*brk == '/') so user@host/path > { > ExtractString(mSpec, &mPath, (brk - mSpec), len - (brk - mSpec)); > return NS_OK; > } > break; > default: > NS_ASSERTION(0, "This just can't be!"); > break; > } 578,580c583 < { < return NS_ERROR_OUT_OF_MEMORY; < } --- > return returnValue; // ERROR! 620,626c623 < // TODO- Fix this. Hack to create tmp only becuz nsString can't < // give us a PR_Malloc (nsCRT/nsAllocator) string < char* tmp = dir.ToNewCString(); < if (!tmp) < return NS_ERROR_OUT_OF_MEMORY; < mDirectory = nsCRT::strdup(tmp); < delete[] tmp; --- > mDirectory = dir.ToNewCString(); 677d673 < nsresult status = NS_ERROR_FAILURE; 782,783c778,782 < NS_ASSERTION(file, "This can't be! ParsePath called without a /Path"); < if (!file) return NS_OK; --- > if (!file) > { > // Treat the whole mPath as file -- this could still have ?, # etc. > file = mPath; > } 788a788,790 > else > DupString(&mDirectory, "/"); > 795,819c797 < if (brk) < { < ExtractString(file, &mFileName, 1 /* skip the leading / */, (brk-file-1)); < //Keep pulling out other pieces... < while (brk) < { < char* lastbrk = brk; < brk = PL_strpbrk(lastbrk+1, delimiters); < switch (*lastbrk) < { < case ';' : /* < ExtractString(lastbrk, &mParam, 1, (brk ? (brk-lastbrk-1) : (len - (lastbrk-file) -1))); < */ < break; < case '?' : ExtractString(lastbrk, &mQuery, 1, (brk ? (brk-lastbrk-1) : (len - (lastbrk-file) -1))); < break; < case '#' : ExtractString(lastbrk, &mRef, 1, (brk ? (brk-lastbrk-1) : (len - (lastbrk-file) -1))); < break; < default: < NS_ASSERTION(0, "This just can't be!"); < break; < } < } < } < else // Everything in the file is just the filename --- > if (!brk) // Everything in the file is just the filename 822a801,821 > ExtractString(file, &mFileName, 1 /* skip the leading / */, (brk-file-1)); > //Keep pulling out other pieces... > while (brk) > { > char* lastbrk = brk; > brk = PL_strpbrk(lastbrk+1, delimiters); > switch (*lastbrk) > { > case ';' : /* > ExtractString(lastbrk, &mParam, 1, (brk ? (brk-lastbrk-1) : (len - (lastbrk-file) -1))); > */ > break; > case '?' : ExtractString(lastbrk, &mQuery, 1, (brk ? (brk-lastbrk-1) : (len - (lastbrk-file) -1))); > break; > case '#' : ExtractString(lastbrk, &mRef, 1, (brk ? (brk-lastbrk-1) : (len - (lastbrk-file) -1))); > break; > default: > NS_ASSERTION(0, "This just can't be!"); > break; > } > } 912,915c911 < // TODO fix when nsString changes < char* tempDirFile = temp.ToNewCString(); < *o_DirFile = nsCRT::strdup(tempDirFile); < delete[] tempDirFile; --- > *o_DirFile = temp.ToNewCString();
1999-07-27 07:40:38 +00:00
mDirectory = dir.ToNewCString();
if (!mDirectory)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
1999-07-10 05:00:23 +00:00
}
NS_IMETHODIMP
nsStdURL::SetFileName(const char* i_FileName)
1999-07-10 05:00:23 +00:00
{
if (!i_FileName)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION( (nsnull != mURLParser), "Parse called without parser!");
2000-02-08 05:55:08 +00:00
if (!mURLParser) return NS_ERROR_NULL_POINTER;
//If it starts with a / then everything is the path.
1999-09-21 22:27:06 +00:00
if ('/' == *i_FileName) {
return SetPath(i_FileName);
1999-09-21 22:27:06 +00:00
}
// Otherwise concatenate Directory and Filename and the call SetPath
nsCAutoString dir;
nsresult status = AppendString(dir,mDirectory,ESCAPED,
nsIIOService::url_Directory);
dir += i_FileName;
char *eNewPath = dir.ToNewCString();
if (!eNewPath)
return NS_ERROR_OUT_OF_MEMORY;
status = SetPath(eNewPath);
CRTFREEIF(eNewPath);
1999-09-21 22:27:06 +00:00
return status;
1999-07-10 05:00:23 +00:00
}
NS_IMETHODIMP
nsStdURL::SetParam(const char* i_Param)
1999-07-10 05:00:23 +00:00
{
CRTFREEIF(mParam);
return DupString(&mParam, (i_Param && (*i_Param == ';')) ?
(i_Param+1) : i_Param);
1999-07-10 05:00:23 +00:00
}
1999-08-12 09:59:24 +00:00
NS_IMETHODIMP
nsStdURL::SetQuery(const char* i_Query)
1999-08-12 09:59:24 +00:00
{
CRTFREEIF(mQuery);
return DupString(&mQuery, (i_Query && (*i_Query == '?')) ?
(i_Query+1) : i_Query);
1999-08-12 09:59:24 +00:00
}
1999-07-10 05:00:23 +00:00
NS_IMETHODIMP
nsStdURL::SetRef(const char* i_Ref)
1999-07-10 05:00:23 +00:00
{
CRTFREEIF(mRef);
return DupString(&mRef, (i_Ref && (*i_Ref == '#')) ?
(i_Ref+1) : i_Ref);
}
NS_IMETHODIMP
nsStdURL::Resolve(const char *relativePath, char **result)
{
nsresult rv = NS_OK;
if (!relativePath) return NS_ERROR_NULL_POINTER;
nsXPIDLCString scheme;
rv = ExtractURLScheme(relativePath, nsnull, nsnull, getter_Copies(scheme));
if (NS_SUCCEEDED(rv)) {
// then aSpec is absolute
rv = DupString(result, relativePath);
char* path = PL_strstr(*result,"://");
if (path) {
path = PL_strstr((char*)(path+3),"/");
if (path)
CoaleseDirs(path);
}
return rv;
}
nsCAutoString finalSpec; // guaranteed to be singlebyte.
// This is another case of an almost absolute URL
if (*relativePath == '/' && *(relativePath+1) != '\0' &&
*(relativePath+1) == '/') {
if (mScheme)
{
rv = AppendString(finalSpec,mScheme,ESCAPED,
nsIIOService::url_Scheme);
finalSpec += ":";
}
finalSpec += relativePath;
*result = finalSpec.ToNewCString();
if (*result) {
char* path = PL_strstr(*result,"://");
if (path) {
path = PL_strstr((char*)(path+3),"/");
if (path)
CoaleseDirs(path);
}
return NS_OK;
} else
return NS_ERROR_OUT_OF_MEMORY;
}
const char *start = relativePath;
if (mScheme)
{
rv = AppendString(finalSpec,mScheme,ESCAPED,nsIIOService::url_Scheme);
finalSpec += "://";
}
rv = AppendPreHost(finalSpec,mUsername,mPassword,ESCAPED);
if (mUsername)
2000-01-14 22:01:56 +00:00
{
finalSpec += '@';
}
if (mHost)
{
rv = AppendString(finalSpec,mHost,HOSTESCAPED,nsIIOService::url_Host);
if (-1 != mPort)
{
char* portBuffer = PR_smprintf(":%d", mPort);
if (!portBuffer)
return NS_ERROR_OUT_OF_MEMORY;
finalSpec += portBuffer;
PR_smprintf_free(portBuffer);
portBuffer = 0;
}
}
if (start) {
switch (*start)
{
case '/':
finalSpec += (char*)start;
break;
case ';':
rv = AppendString(finalSpec,mDirectory,ESCAPED,
nsIIOService::url_Directory);
rv = AppendFileName(finalSpec,mFileBaseName,mFileExtension,
ESCAPED);
finalSpec += (char*)start;
break;
case '?':
rv = AppendString(finalSpec,mDirectory,ESCAPED,
nsIIOService::url_Directory);
rv = AppendFileName(finalSpec,mFileBaseName,mFileExtension,
ESCAPED);
if (mParam)
{
finalSpec += ';';
rv = AppendString(finalSpec,mParam,ESCAPED,
nsIIOService::url_Param);
}
finalSpec += (char*)start;
break;
case '#':
rv = AppendString(finalSpec,mDirectory,ESCAPED,
nsIIOService::url_Directory);
rv = AppendFileName(finalSpec,mFileBaseName,mFileExtension,
ESCAPED);
if (mParam)
{
finalSpec += ';';
rv = AppendString(finalSpec,mParam,ESCAPED,
nsIIOService::url_Param);
}
if (mQuery)
{
finalSpec += '?';
rv = AppendString(finalSpec,mQuery,ESCAPED,
nsIIOService::url_Query);
}
finalSpec += (char*)start;
break;
default:
rv = AppendString(finalSpec,mDirectory,ESCAPED,
nsIIOService::url_Directory);
finalSpec += (char*)start;
}
}
*result = finalSpec.ToNewCString();
if (*result) {
char* path = PL_strstr(*result,"://");
if (path) {
path = PL_strstr((char*)(path+3),"/");
if (path)
CoaleseDirs(path);
}
return NS_OK;
} else
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult
nsStdURL::GetPath(char** o_Path)
{
1999-09-21 22:27:06 +00:00
//Take all the elements of the path and construct it
nsCAutoString path;
nsresult rv = NS_OK;
if (mDirectory)
{
rv = AppendString(path,mDirectory,ESCAPED,nsIIOService::url_Directory);
if (NS_FAILED(rv))
return rv;
}
rv = AppendFileName(path,mFileBaseName,mFileExtension, ESCAPED);
if (NS_FAILED(rv))
return rv;
1999-08-12 09:59:24 +00:00
if (mParam)
{
path += ';';
rv = AppendString(path,mParam,ESCAPED,nsIIOService::url_Param);
if (NS_FAILED(rv))
return rv;
}
if (mQuery)
{
path += '?';
rv = AppendString(path,mQuery,ESCAPED,nsIIOService::url_Query);
if (NS_FAILED(rv))
return rv;
}
if (mRef)
{
path += '#';
rv = AppendString(path,mRef,ESCAPED,nsIIOService::url_Ref);
if (NS_FAILED(rv))
return rv;
}
*o_Path = path.ToNewCString();
return (*o_Path ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
1999-07-10 05:00:23 +00:00
}
nsresult
nsStdURL::GetDirectory(char** o_Directory)
{
nsCAutoString directory;
nsresult rv = NS_OK;
rv = AppendString(directory,mDirectory,ESCAPED,
nsIIOService::url_Directory);
if (NS_FAILED(rv))
return rv;
*o_Directory = directory.ToNewCString();
return (*o_Directory ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
}
NS_METHOD
nsStdURL::SetSpec(const char* i_Spec)
{
char* eSpec = nsnull;
nsresult rv = DupString(&eSpec,i_Spec);
if (NS_FAILED(rv)){
CRTFREEIF(eSpec);
return rv;
}
// Skip leading spaces and control-characters
char* fwdPtr= (char*) eSpec;
while (fwdPtr && (*fwdPtr > '\0') && (*fwdPtr <= ' '))
fwdPtr++;
// Strip linebreaks
char* copyToPtr = 0;
char* midPtr = fwdPtr;
while (midPtr && (*midPtr != '\0')) {
while ((*midPtr == '\r') || (*midPtr == '\n')) { // if linebreak
if (!copyToPtr)
copyToPtr = midPtr; // start copying
midPtr++; // skip linebreak
}
if (copyToPtr) { // if copying
*copyToPtr = *midPtr;
copyToPtr++;
}
midPtr++;
}
if (copyToPtr) { // If we removed linebreaks, copyToPtr is the end of the string
midPtr = copyToPtr;
}
// Remove trailing spaces and control-characters
while ((midPtr-fwdPtr) >= 0) {
midPtr--;
if ((*midPtr > ' ') || (*midPtr <= '\0')) // UTF-8 chars < 0?
break;
}
if (midPtr && (*midPtr != '\0'))
*(midPtr+1) = '\0'; // Restore trailing null
// If spec is being rewritten clean up everything-
CRTFREEIF(mScheme);
CRTFREEIF(mUsername);
CRTFREEIF(mPassword);
CRTFREEIF(mHost);
mPort = -1;
CRTFREEIF(mDirectory);
CRTFREEIF(mFileBaseName);
CRTFREEIF(mFileExtension);
1999-08-27 12:38:06 +00:00
CRTFREEIF(mParam);
CRTFREEIF(mQuery);
CRTFREEIF(mRef);
rv = Parse(fwdPtr);
CRTFREEIF(eSpec);
return rv;
}
NS_METHOD
nsStdURL::SetPreHost(const char* i_PreHost)
{
NS_PRECONDITION( (nsnull != mURLParser), "Parse called without parser!");
2000-02-08 05:55:08 +00:00
if (!mURLParser) return NS_ERROR_NULL_POINTER;
CRTFREEIF(mUsername);
CRTFREEIF(mPassword);
return mURLParser->ParsePreHost(i_PreHost,&mUsername,&mPassword);
}
NS_METHOD
nsStdURL::SetPath(const char* i_Path)
{
NS_PRECONDITION( (nsnull != mURLParser), "Parse called without parser!");
2000-02-08 05:55:08 +00:00
if (!mURLParser) return NS_ERROR_NULL_POINTER;
CRTFREEIF(mDirectory);
CRTFREEIF(mFileBaseName);
CRTFREEIF(mFileExtension);
CRTFREEIF(mParam);
CRTFREEIF(mQuery);
CRTFREEIF(mRef);
return mURLParser->ParseAtDirectory((char*)i_Path, &mDirectory,
&mFileBaseName,
&mFileExtension, &mParam,
&mQuery, &mRef);
}
NS_METHOD
nsStdURL::GetFilePath(char **o_DirFile)
{
1999-08-27 12:38:06 +00:00
if (!o_DirFile)
return NS_ERROR_NULL_POINTER;
nsresult rv = NS_OK;
nsCAutoString temp;
1999-08-27 12:38:06 +00:00
if (mDirectory)
{
rv = AppendString(temp,mDirectory,ESCAPED,nsIIOService::url_Directory);
1999-08-27 12:38:06 +00:00
}
rv = AppendFileName(temp,mFileBaseName,mFileExtension,ESCAPED);
if (NS_FAILED(rv))
return rv;
1999-08-27 12:38:06 +00:00
*o_DirFile = temp.ToNewCString();
if (!*o_DirFile)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_METHOD
nsStdURL::GetFileName(char **o_FileName)
{
if (!o_FileName)
return NS_ERROR_NULL_POINTER;
nsresult rv = NS_OK;
if (mFileBaseName || mFileExtension) {
nsCAutoString temp;
rv = AppendFileName(temp,mFileBaseName,mFileExtension,ESCAPED);
if (NS_FAILED(rv))
return rv;
*o_FileName = temp.ToNewCString();
if (!*o_FileName)
return NS_ERROR_OUT_OF_MEMORY;
} else {
*o_FileName = nsnull;
}
return NS_OK;
}
NS_METHOD
nsStdURL::SetFilePath(const char *filePath)
{
return SetPath(filePath);
}
2000-01-24 21:28:28 +00:00
NS_IMETHODIMP
nsStdURL::GetFile(nsIFile * *aFile)
{
nsresult rv = NS_OK;
2000-01-24 21:28:28 +00:00
if (nsCRT::strcasecmp(mScheme, "file") != 0) {
// if this isn't a file: URL, then we can't return an nsIFile
return NS_ERROR_FAILURE;
}
NS_ASSERTION(mUsername == nsnull, "file: with mUsername");
2000-01-24 21:28:28 +00:00
// we do not use the path cause it can contain the # char
nsCAutoString path;
if (mDirectory)
{
rv = AppendString(path,mDirectory,ESCAPED,nsIIOService::url_Directory);
#if defined( XP_MAC )
// Now Swap the / and colons to convert back to a mac path
// Do this only on the mDirectory portion - not mFileBaseName or mFileExtension
SwapSlashColon( (char*)path.GetBuffer() );
#endif
}
rv = AppendFileName(path,mFileBaseName,mFileExtension,ESCAPED);
2000-01-24 21:28:28 +00:00
#ifdef XP_PC
if (path.CharAt(2) == '|')
2000-01-24 21:28:28 +00:00
path.SetCharAt(':', 2);
// cut off the leading '/'
if (path.CharAt(0) == '/')
path.Cut(0, 1);
else if (mHost) {
// Deal with the case where the user type file://C|/ (2 slashes instead of 3).
// In this case, the C| ends up as the host name (ugh).
nsCAutoString host(mHost);
PRInt32 len = host.Length();
if (len == 2 && host.CharAt(1) == '|') {
host.SetCharAt(':', 1);
path.Insert(host, 0);
}
}
2000-01-24 21:28:28 +00:00
path.ReplaceChar('/', '\\');
#endif
nsUnescape((char*)path.GetBuffer());
#if defined( XP_MAC )
// wack off leading :'s
if (path.CharAt(0) == ':')
path.Cut(0, 1);
#endif
2000-01-24 21:28:28 +00:00
nsCOMPtr<nsILocalFile> localFile;
rv = NS_NewLocalFile(path, PR_FALSE, getter_AddRefs(localFile));
2000-01-24 21:28:28 +00:00
mFile = localFile;
*aFile = mFile;
NS_IF_ADDREF(*aFile);
return rv;
}
NS_IMETHODIMP
nsStdURL::SetFile(nsIFile * aFile)
{
nsresult rv;
2000-01-24 21:28:28 +00:00
mFile = aFile;
// set up this URL to denote the nsIFile
SetScheme("file");
CRTFREEIF(mUsername);
CRTFREEIF(mPassword);
CRTFREEIF(mHost);
mPort = -1;
2000-01-24 21:28:28 +00:00
char* ePath = nsnull;
nsCAutoString escPath;
rv = aFile->GetPath(&ePath);
if (NS_SUCCEEDED(rv)) {
#if defined (XP_PC)
// Replace \ with / to convert to an url
char* s = ePath;
while (*s)
{
2000-05-16 21:41:14 +00:00
#ifndef XP_OS2
// 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++;
2000-05-16 21:41:14 +00:00
} else
#endif
if (*s == '\\')
*s = '/';
s++;
}
#endif
#if defined( XP_MAC )
// Swap the / and colons to convert to an url
SwapSlashColon(ePath);
#endif
// Escape the path with the directory mask
rv = nsURLEscape(ePath,nsIIOService::url_Directory+
nsIIOService::url_Forced,escPath);
if (NS_SUCCEEDED(rv)) {
PRBool dir;
rv = aFile->IsDirectory(&dir);
if (NS_SUCCEEDED(rv) && dir && escPath[escPath.Length() - 1] != '/') {
// make sure we have a trailing slash
escPath += "/";
}
rv = SetPath(escPath.GetBuffer());
}
}
CRTFREEIF(ePath);
return rv;
2000-01-24 21:28:28 +00:00
}
////////////////////////////////////////////////////////////////////////////////