Temporary checkin. Brought in the original implementations. Will need some cleaning now...

This commit is contained in:
gagan%netscape.com 1999-04-09 02:31:48 +00:00
parent 40b727ed83
commit 31c335db36
5 changed files with 793 additions and 118 deletions

View File

@ -17,7 +17,7 @@ MODULE = netwerk
DEPTH = ..\..\..
LCFLAGS = -DWIN32_LEAN_AND_MEAN
LCFLAGS = -DWIN32_LEAN_AND_MEAN -D_IMPL_NS_NET
LIBRARY_NAME=netwerkbase_s

View File

@ -18,7 +18,7 @@
#include "nsNetService.h"
#include "nsIProtocolHandler.h"
#include "nsUrl.h"
#include "nsURL.h"
#include "nscore.h"
#include "nsString2.h"
#include "nsIServiceManager.h"
@ -49,8 +49,9 @@ NS_IMPL_ISUPPORTS(nsNetService, nsINetService::GetIID());
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsNetService::GetProtocolHandler(nsIUrl* url, nsIProtocolHandler* *result)
nsNetService::GetProtocolHandler(nsIURL* url, nsIProtocolHandler* *result)
{
#if 0 // will fix later...
nsresult rv;
const char* scheme;
@ -70,6 +71,7 @@ nsNetService::GetProtocolHandler(nsIUrl* url, nsIProtocolHandler* *result)
if (NS_FAILED(rv)) return rv;
*result = handler;
#endif // fix TODO
return NS_OK;
}
@ -90,35 +92,55 @@ nsNetService::NewConnectionGroup(nsIConnectionGroup* *result)
}
NS_IMETHODIMP
nsNetService::NewURL(nsIUrl* *result,
nsNetService::NewURL(nsIURL* *result,
const char* aSpec,
const nsIUrl* aBaseURL,
const nsIURL* aBaseURL,
nsISupports* aContainer)
{
#if 0
nsresult rv;
nsUrl* url = new nsUrl();
if (url == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
rv = url->Init(aSpec, aBaseURL, aContainer);
if (NS_FAILED(rv)) {
delete url;
return rv;
nsURL* url;
if (aBaseURL)
{
aBaseURL->Clone(&url);
PR_ASSERT(url);
if (!url)
return NS_ERROR_OUT_OF_MEMORY;
rv = url->MakeAbsoluteFrom(aSpec);
if (NS_FAILED(rv))
{
delete url;
url = 0;
return rv;
}
}
else
{
url = new nsURL(aSpec);
if (nsnull == url)
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(url);
*result = url;
#endif // TODO
return NS_OK;
}
NS_IMETHODIMP
nsNetService::Open(nsIUrl* url, nsISupports* eventSink,
nsNetService::Open(nsIURL* url, nsISupports* eventSink,
nsIConnectionGroup* group,
nsIProtocolConnection* *result)
nsIProtocolInstance* *result)
{
#if 0
nsresult rv;
nsIProtocolHandler* handler;
rv = GetProtocolHandler(url, &handler);
if (NS_FAILED(rv)) return rv;
return handler->Open(url, eventSink, group, result);
#endif // TODO - there is no open on the handler.
return NS_OK;
}
NS_IMETHODIMP

View File

@ -27,15 +27,15 @@ public:
NS_DECL_ISUPPORTS
// nsINetService methods:
NS_IMETHOD GetProtocolHandler(nsIUrl* url, nsIProtocolHandler* *result);
NS_IMETHOD GetProtocolHandler(nsIURL* url, nsIProtocolHandler* *result);
NS_IMETHOD NewConnectionGroup(nsIConnectionGroup* *result);
NS_IMETHOD NewURL(nsIUrl* *result,
NS_IMETHOD NewURL(nsIURL* *result,
const char* aSpec,
const nsIUrl* aBaseURL,
nsISupports* aContainer);
NS_IMETHOD Open(nsIUrl* url, nsISupports* eventSink,
const nsIURL* aBaseURL = 0,
nsISupports* aContainer = 0);
NS_IMETHOD Open(nsIURL* url, nsISupports* eventSink,
nsIConnectionGroup* aGroup,
nsIProtocolConnection* *result);
nsIProtocolInstance* *result);
NS_IMETHOD HasActiveConnections();
// nsNetService methods:

View File

@ -1,118 +1,610 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* Version 1.0 (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 NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* 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 Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsUrl.h"
//
// TODOs for this file-
// - Check error states returned from all occurences of ExtractPortFrom
// - Grep on other TODOs...
//
////////////////////////////////////////////////////////////////////////////////
// nsUrl methods:
#include "nsURL.h"
#include <stdlib.h>
#include "plstr.h"
#include "nsIProtocolHandler.h"
#include "nsIComponentManager.h"
nsUrl::nsUrl()
{
NS_INIT_REFCNT();
static const PRInt32 DEFAULT_PORT = -1;
#define SET_POSITION(__part,__start,__length) \
{ \
m_Position[__part][0] = __start; \
m_Position[__part][1] = __length; \
}
nsUrl::~nsUrl()
NS_NET
nsIURL* CreateURL(const char* i_URL)
{
nsIURL* pReturn = new nsURL(i_URL);
if (pReturn)
pReturn->AddRef();
return pReturn;
}
nsURL::nsURL(const char* i_URL):
m_Port(DEFAULT_PORT),
mRefCnt(0)
{
NS_PRECONDITION( (0 != i_URL), "No url string specified!");
if (i_URL)
{
m_URL = new char[PL_strlen(i_URL) + 1];
if (m_URL)
{
PL_strcpy(m_URL, i_URL);
}
}
else
{
m_URL = new char[1];
*m_URL = '\0';
}
for (int i=0; i<TOTAL_PARTS; ++i)
{
for (int j=0; j<2; ++j)
{
m_Position[i][j] = -1;
}
}
Parse();
}
nsURL::~nsURL()
{
if (m_URL)
{
delete[] m_URL;
m_URL = 0;
}
}
NS_IMPL_ADDREF(nsURL);
PRBool
nsURL::Equals(const nsIURI* i_URI) const
{
NS_NOTYETIMPLEMENTED("Eeeks!");
return PR_FALSE;
}
nsresult
nsUrl::Init(const char* aSpec,
const nsIUrl* aBaseURL,
nsISupports* aContainer)
nsURL::Extract(const char* *o_OutputString, nsURL::Part i_id) const
{
int i = (int) i_id;
if (o_OutputString)
{
*o_OutputString = new char(m_Position[i][1]+1);
if (!*o_OutputString)
return NS_ERROR_OUT_OF_MEMORY;
char* dest = (char*) *o_OutputString;
char* src = m_URL + m_Position[i][0];
for (int j=0; j<m_Position[i][1]; ++j)
{
*dest++ = *src++;
}
*dest = '\0';
return NS_OK;
}
return NS_ERROR_URL_PARSING;
}
nsresult
nsURL::ExtractPortFrom(int start, int length)
{
char* port = new char[length +1];
if (!port)
{
return NS_ERROR_OUT_OF_MEMORY;
}
PL_strncpy(port, m_URL+start, length);
*(port + length) = '\0';
m_Port = atoi(port);
delete[] port;
return NS_OK;
}
NS_IMPL_ISUPPORTS(nsUrl, nsIUrl::GetIID());
////////////////////////////////////////////////////////////////////////////////
// nsIUrl methods:
NS_IMETHODIMP
nsUrl::GetScheme(const char* *result)
nsresult
nsURL::GetStream(nsIInputStream* *o_InputStream)
{
NS_PRECONDITION( (0 != m_URL), "GetStream called on empty url!");
nsresult result = NS_OK; // change to failure
//OpenProtocolInstance and request the input stream
nsIProtocolInstance* pi = 0;
result = OpenProtocolInstance(&pi);
if (NS_OK != result)
return result;
return pi->GetInputStream(o_InputStream);
}
nsresult nsURL::OpenProtocolInstance(nsIProtocolInstance* *o_ProtocolInstance)
{
const char* scheme =0;
GetScheme(&scheme);
// If the expected behaviour is to have http as the default scheme, a
// caller must check that before calling this function. We will not
// make any assumptions here.
if (0 == scheme)
return NS_ERROR_BAD_URL;
nsIProtocolHandler *pHandler=0;
nsresult rv = nsComponentManager::CreateInstance(
NS_COMPONENT_NETSCAPE_NETWORK_PROTOCOLS "http", // TODO replace!
nsnull,
nsIProtocolHandler::GetIID(),
(void**)&pHandler);
//return pHandler ? pHandler->GetProtocolInstance(this, o_ProtocolInstance) : rv;
return NS_ERROR_BAD_URL; // testing
}
// This code will need thorough testing. A lot of this has to do with
// usability and expected behaviour when a user types something in the
// location bar.
nsresult nsURL::Parse(void)
{
NS_PRECONDITION( (0 != m_URL), "Parse called on empty url!");
if (!m_URL)
{
return NS_ERROR_URL_PARSING;
}
//Remember to remove leading/trailing spaces, etc. TODO
int len = PL_strlen(m_URL);
static const char delimiters[] = "/:@"; //this order is optimized.
char* brk = PL_strpbrk(m_URL, delimiters);
char* lastbrk = brk;
if (brk)
{
switch (*brk)
{
case '/' :
// If the URL starts with a slash then everything is a path
if (brk == m_URL)
{
SET_POSITION(PATH, 0, len);
return NS_OK;
}
else // The first part is host, so its host/path
{
SET_POSITION(HOST, 0, (brk - m_URL));
SET_POSITION(PATH, (brk - m_URL), (len - (brk - m_URL)));
return NS_OK;
}
break;
case ':' :
// If the first colon is followed by // then its definitely a spec
if ((*(brk+1) == '/') && (*(brk+2) == '/')) // e.g. http://
{
SET_POSITION(SCHEME, 0, (brk - m_URL));
lastbrk = brk+3;
brk = PL_strpbrk(lastbrk, delimiters);
if (brk)
{
switch (*brk)
{
case '/' : // standard case- http://host/path
SET_POSITION(HOST, (lastbrk - m_URL), (brk - lastbrk));
SET_POSITION(PATH, (brk - m_URL), (len - (brk - m_URL)));
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 at after this colon, so...
char* atSign = PL_strchr(brk, '@');
if (atSign)
{
SET_POSITION(PREHOST, (lastbrk - m_URL), (atSign - lastbrk));
brk = PL_strpbrk(atSign+1, "/:");
if (brk) // http://user:pass@host:port/path or http://user:pass@host/path
{
SET_POSITION(HOST, (atSign+1 - m_URL), (brk - (atSign+1)));
if (*brk == '/')
{
SET_POSITION(PATH, (brk - m_URL), len - (brk - m_URL));
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
{
ExtractPortFrom((lastbrk - m_URL), (brk-lastbrk));
SET_POSITION(PATH, (brk-m_URL), len - (brk-m_URL));
return NS_OK;
}
else // http://user:pass@host:port
{
ExtractPortFrom((lastbrk - m_URL), len - (lastbrk - m_URL));
return NS_OK;
}
}
}
else // its just http://user:pass@host
{
SET_POSITION(HOST, (atSign+1 - m_URL), len - (atSign+1 - m_URL));
return NS_OK;
}
}
else // definitely the port option, i.e. http://host:port/path
{
SET_POSITION(HOST, (lastbrk-m_URL), (brk-lastbrk));
lastbrk = brk+1;
brk = PL_strchr(lastbrk, '/');
if (brk) // http://host:port/path
{
ExtractPortFrom((lastbrk-m_URL),(brk-lastbrk));
SET_POSITION(PATH, (brk-m_URL), len - (brk-m_URL));
return NS_OK;
}
else // http://host:port
{
ExtractPortFrom((lastbrk-m_URL),len - (lastbrk-m_URL));
return NS_OK;
}
}
}
break;
case '@' :
// http://user@host...
{
SET_POSITION(PREHOST, (lastbrk-m_URL), (brk-lastbrk));
lastbrk = brk+1;
brk = PL_strpbrk(lastbrk, ":/");
if (brk)
{
SET_POSITION(HOST, (lastbrk-m_URL), (brk - lastbrk));
if (*brk == ':') // http://user@host:port...
{
lastbrk = brk+1;
brk = PL_strchr(lastbrk, '/');
if (brk) // http://user@host:port/path
{
ExtractPortFrom((lastbrk-m_URL),(brk-lastbrk));
SET_POSITION(PATH, (brk-m_URL), len - (brk-m_URL));
return NS_OK;
}
else // http://user@host:port
{
ExtractPortFrom((lastbrk-m_URL),len - (lastbrk-m_URL));
return NS_OK;
}
}
else // (*brk == '/') so no port just path i.e. http://user@host/path
{
SET_POSITION(PATH, (brk - m_URL), len - (brk - m_URL));
return NS_OK;
}
}
else // its just http://user@host
{
SET_POSITION(HOST, (lastbrk+1 - m_URL), len - (lastbrk+1 - m_URL));
return NS_OK;
}
}
break;
default: NS_POSTCONDITION(0, "This just can't be!");
break;
}
}
else // everything else is a host, as in http://host
{
SET_POSITION(HOST, (lastbrk - m_URL), len - (lastbrk - m_URL));
return NS_OK;
}
}
else // host:port...
{
SET_POSITION(HOST, 0, (brk - m_URL));
lastbrk = brk+1;
brk = PL_strpbrk(lastbrk, delimiters);
if (brk)
{
switch (*brk)
{
case '/' : // The path, so its host:port/path
ExtractPortFrom(lastbrk-m_URL, brk-lastbrk);
SET_POSITION(PATH, brk- m_URL, len - (brk-m_URL));
return NS_OK;
break;
case ':' :
return NS_ERROR_URL_PARSING;
break;
case '@' :
// This is a special case of user:pass@host... so
// Cleanout our earliar knowledge of host
SET_POSITION(HOST, -1, -1);
SET_POSITION(PREHOST, 0, (brk-m_URL));
lastbrk = brk+1;
brk = PL_strpbrk(lastbrk, ":/");
if (brk)
{
SET_POSITION(HOST, (lastbrk-m_URL), (brk-lastbrk));
if (*brk == ':') // user:pass@host:port...
{
lastbrk = brk+1;
brk = PL_strchr(lastbrk, '/');
if (brk) // user:pass@host:port/path
{
ExtractPortFrom((lastbrk-m_URL),(brk-lastbrk));
SET_POSITION(PATH, (brk-m_URL), len - (brk-m_URL));
return NS_OK;
}
else // user:pass@host:port
{
ExtractPortFrom((lastbrk-m_URL),len - (lastbrk-m_URL));
return NS_OK;
}
}
else // (*brk == '/') so user:pass@host/path
{
SET_POSITION(PATH, (brk - m_URL), len - (brk - m_URL));
return NS_OK;
}
}
else // its user:pass@host so everthing else is just the host
{
SET_POSITION(HOST, (lastbrk-m_URL), len - (lastbrk-m_URL));
return NS_OK;
}
break;
default: NS_POSTCONDITION(0, "This just can't be!");
break;
}
}
else // Everything else is just the port
{
ExtractPortFrom(lastbrk-m_URL, len - (lastbrk-m_URL));
return NS_OK;
}
}
break;
case '@' :
//Everything before the @ is the prehost stuff
SET_POSITION(PREHOST, 0, brk-m_URL);
lastbrk = brk+1;
brk = PL_strpbrk(lastbrk, ":/");
if (brk)
{
SET_POSITION(HOST, (lastbrk-m_URL), (brk-lastbrk));
if (*brk == ':') // user@host:port...
{
lastbrk = brk+1;
brk = PL_strchr(lastbrk, '/');
if (brk) // user@host:port/path
{
ExtractPortFrom((lastbrk-m_URL),(brk-lastbrk));
SET_POSITION(PATH, (brk-m_URL), len - (brk-m_URL));
return NS_OK;
}
else // user@host:port
{
ExtractPortFrom((lastbrk-m_URL),len - (lastbrk-m_URL));
return NS_OK;
}
}
else // (*brk == '/') so user@host/path
{
SET_POSITION(PATH, (brk - m_URL), len - (brk - m_URL));
return NS_OK;
}
}
else // its user@host so everything else is just the host
{
SET_POSITION(HOST, (lastbrk-m_URL), (len - (lastbrk-m_URL)));
return NS_OK;
}
break;
default:
NS_POSTCONDITION(0, "This just can't be!");
break;
}
}
else // everything is a host
{
SET_POSITION(HOST, 0, len);
}
return NS_OK;
}
nsresult
nsURL::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr)
return NS_ERROR_NULL_POINTER;
*aInstancePtr = NULL;
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(nsIURL::GetIID())) {
*aInstancePtr = (void*) ((nsIURL*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsIURI::GetIID())) {
*aInstancePtr = (void*) ((nsIURI*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) ((nsISupports*)this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_RELEASE(nsURL);
nsresult
nsURL::SetHost(const char* i_Host)
{
NS_NOTYETIMPLEMENTED("Eeeks!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsUrl::SetScheme(const char* scheme)
nsresult
nsURL::SetPath(const char* i_Path)
{
NS_NOTYETIMPLEMENTED("Eeeks!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsUrl::GetPreHost(const char* *result)
nsresult
nsURL::SetPort(PRInt32 i_Port)
{
if (m_Port != i_Port)
{
m_Port = i_Port;
if (DEFAULT_PORT == m_Port)
{
//Just REMOVE the earliar one.
NS_NOTYETIMPLEMENTED("Eeeks!");
}
else
{
//Insert the string equivalent
NS_NOTYETIMPLEMENTED("Eeeks!");
}
Parse();
}
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsUrl::SetPreHost(const char* preHost)
nsresult
nsURL::SetPreHost(const char* i_PreHost)
{
NS_NOTYETIMPLEMENTED("Eeeks!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsUrl::GetHost(const char* *result)
nsresult
nsURL::SetScheme(const char* i_Scheme)
{
NS_NOTYETIMPLEMENTED("Eeeks!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsUrl::SetHost(const char* host)
#ifdef DEBUG
nsresult
nsURL::DebugString(const char* *o_String) const
{
return NS_ERROR_NOT_IMPLEMENTED;
}
if (!m_URL)
return NS_OK;
const char* tempBuff = 0;
char* tmp = new char[PL_strlen(m_URL) + 64];
char* tmp2 = tmp;
for (int i=PL_strlen(m_URL)+64; i>0 ; --i)
*tmp2++ = '\0';
/*///
PL_strcpy(tmp, "m_URL= ");
PL_strcat(tmp, m_URL);
GetScheme(&tempBuff);
PL_strcat(tmp, "\nScheme= ");
PL_strcat(tmp, tempBuff);
GetPreHost(&tempBuff);
PL_strcat(tmp, "\nPreHost= ");
PL_strcat(tmp, tempBuff);
GetHost(&tempBuff);
PL_strcat(tmp, "\nHost= ");
PL_strcat(tmp, tempBuff);
char* tempPort = new char[6];
if (tempPort)
{
itoa(m_Port, tempPort, 10);
PL_strcat(tmp, "\nPort= ");
PL_strcat(tmp, tempPort);
delete[] tempPort;
}
else
PL_strcat(tmp, "\nPort couldn't be conv'd to string!");
NS_IMETHODIMP
nsUrl::GetPort(PRInt32 *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
GetPath(&tempBuff);
PL_strcat(tmp, "\nPath= ");
PL_strcat(tmp, tempBuff);
PL_strcat(tmp, "\n");
/*///
char delimiter[] = ",";
#define TEMP_AND_DELIMITER PL_strcat(tmp, tempBuff); \
PL_strcat(tmp, delimiter)
NS_IMETHODIMP
nsUrl::SetPort(PRInt32 port)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
PL_strcpy(tmp, m_URL);
PL_strcat(tmp, "\n");
NS_IMETHODIMP
nsUrl::GetPath(const char* *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
GetScheme(&tempBuff);
TEMP_AND_DELIMITER;
NS_IMETHODIMP
nsUrl::SetPath(const char* path)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
GetPreHost(&tempBuff);
TEMP_AND_DELIMITER;
NS_IMETHODIMP
nsUrl::Equals(const nsIUrl* other)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
GetHost(&tempBuff);
TEMP_AND_DELIMITER;
NS_IMETHODIMP
nsUrl::ToNewCString(const char* *uriString)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
char* tempPort = new char[6];
if (tempPort)
{
itoa(m_Port, tempPort, 10);
PL_strcat(tmp, tempPort);
PL_strcat(tmp, delimiter);
delete[] tempPort;
}
else
PL_strcat(tmp, "\nPort couldn't be conv'd to string!");
////////////////////////////////////////////////////////////////////////////////
GetPath(&tempBuff);
PL_strcat(tmp, tempBuff);
PL_strcat(tmp, "\n");
//*///
*o_String = tmp;
return NS_OK;
}
#endif // DEBUG

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
@ -16,50 +16,211 @@
* Reserved.
*/
#ifndef nsUrl_h__
#define nsUrl_h__
#ifndef _nsURL_h_
#define _nsURL_h_
#include "nsIUrl.h"
/*
The nsURL class holds the default implementation of the nsIURL class.
For explanation on the implementation see -
class nsUrl : public nsIUrl
http://www.w3.org/Addressing/URL/url-spec.txt
and the headers for nsIURL.h and nsIURI.h
- Gagan Saksena
*/
#include "nsIURL.h"
class nsURL : public nsIURL
{
public:
//Constructor
nsURL(const char* i_URL);
//Functions from nsISupports
NS_DECL_ISUPPORTS
////////////////////////////////////////////////////////////////////////////
// nsIUrl methods:
//Functions from nsIURI
//Core parsing functions.
/*
The Scheme is the protocol that this URL refers to.
*/
NS_METHOD GetScheme(const char* *o_Scheme) const;
NS_METHOD SetScheme(const char* i_Scheme);
NS_IMETHOD GetScheme(const char* *result);
NS_IMETHOD SetScheme(const char* scheme);
/*
The PreHost portion includes elements like the optional
username:password, or maybe other scheme specific items.
*/
NS_METHOD GetPreHost(const char* *o_PreHost) const;
NS_METHOD SetPreHost(const char* i_PreHost);
NS_IMETHOD GetPreHost(const char* *result);
NS_IMETHOD SetPreHost(const char* preHost);
/*
The Host is the internet domain name to which this URL refers.
Note that it could be an IP address as well.
*/
NS_METHOD GetHost(const char* *o_Host) const;
NS_METHOD SetHost(const char* i_Host);
NS_IMETHOD GetHost(const char* *result);
NS_IMETHOD SetHost(const char* host);
/*
A return value of -1 indicates that no port value is set and the
implementor of the specific scheme will use its default port.
Similarly setting a value of -1 indicates that the default is to be used.
Thus as an example-
for HTTP, Port 80 is same as a return value of -1.
However after setting a port (even if its default), the port number will
appear in the ToString function.
*/
NS_METHOD_(PRInt32) GetPort(void) const;
NS_METHOD SetPort(PRInt32 i_Port);
NS_IMETHOD GetPort(PRInt32 *result);
NS_IMETHOD SetPort(PRInt32 port);
/*
Note that the path includes the leading '/' Thus if no path is
available the GetPath will return a "/"
For SetPath if none is provided, one would be prefixed to the path.
*/
NS_METHOD GetPath(const char* *o_Path) const;
NS_METHOD SetPath(const char* i_Path);
NS_IMETHOD GetPath(const char* *result);
NS_IMETHOD SetPath(const char* path);
//Functions from nsIURL.h
NS_IMETHOD Equals(const nsIUrl* other);
/*
Create a copy of this url in the specified location.
Use this as much as possible instead of creating a fresh one
each time since we save on the parsing overhead.
*/
NS_METHOD Clone(nsURL* *o_URL) const;
NS_IMETHOD ToNewCString(const char* *uriString);
#ifdef DEBUG
NS_METHOD DebugString(const char* *o_URLString) const;
#endif //DEBUG
////////////////////////////////////////////////////////////////////////////
// nsUrl methods:
/*
Note: The GetStream function also opens a connection using
the available information in the URL. This is the same as
calling OpenInputStream on the connection returned from
OpenProtocolInstance.
*/
NS_METHOD GetStream(nsIInputStream* *o_InputStream);
nsUrl();
virtual ~nsUrl();
/*
MakeAbsoluteFrom function takes a new string that is a relative url,
and converts this object to represent the final form. As an example
if this is "http://foo/bar" and we call MakeAbsoluteFrom("/baz")
then this will change to "http://foo/baz" There is a whole series
of possibilities here. Check this URL for more details (TODO -Gagan)
*/
NS_METHOD MakeAbsoluteFrom(const char* i_NewURL);
nsresult Init(const char* aSpec,
const nsIUrl* aBaseURL,
nsISupports* aContainer);
/*
The OpenProtocolInstance method sets up the connection as decided by the
protocol implementation. This may then be used to get various
connection specific details like the input and the output streams
associated with the connection, or the header information by querying
on the connection type which will be protocol specific.
*/
NS_METHOD OpenProtocolInstance(nsIProtocolInstance* *o_ProtocolInstance);
//Other utility functions
/*
Note that this comparison is only on char* level. Cast nsIURL to
the scheme specific URL to do a more thorough check. For example--
in HTTP-
http://foo.com:80 == http://foo.com
but this function through nsIURL alone will not return equality.
*/
NS_METHOD_(PRBool) Equals(const nsIURI* i_URI) const;
/*
Writes a string representation of the URL.
*/
NS_METHOD ToString(const char* *o_URLString) const;
protected:
//Called only from Release
virtual ~nsURL();
typedef enum
{
SCHEME,
PREHOST,
HOST,
PATH,
TOTAL_PARTS // Must always be the last one.
} Part;
/*
Parses the portions of the URL into individual pieces
like spec, prehost, host, path etc.
*/
NS_METHOD Parse();
/*
Extract a portion from the given part id.
*/
NS_METHOD Extract(const char* *o_OutputString, Part i_id) const;
/*
This holds the offsets and the lengths of each part.
Optimizes on storage and speed.
*/
int m_Position[TOTAL_PARTS][2];
char* m_URL;
PRInt32 m_Port;
private:
NS_METHOD ExtractPortFrom(int start, int length);
};
#endif // nsUrl_h__
inline
NS_METHOD
nsURL::GetHost(const char* *o_Host) const
{
return Extract(o_Host, HOST);
}
inline
NS_METHOD
nsURL::GetScheme(const char* *o_Scheme) const
{
return Extract(o_Scheme, SCHEME);
}
inline
NS_METHOD
nsURL::GetPreHost(const char* *o_PreHost) const
{
return Extract(o_PreHost, PREHOST);
}
inline
NS_METHOD_(PRInt32)
nsURL::GetPort() const
{
return m_Port;
}
inline
NS_METHOD
nsURL::GetPath(const char* *o_Path) const
{
return Extract(o_Path, PATH);
}
inline
NS_METHOD
nsURL::ToString(const char* *o_URLString) const
{
*o_URLString = m_URL;
return NS_OK;
}
//Possible bad url passed.
#define NS_ERROR_URL_PARSING NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 100);
#define NS_ERROR_BAD_URL NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 101);
#endif /* _nsURL_h_ */