// $Id: webaddr.cpp 1282 2006-06-09 09:46:49Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ #include "camtypes.h" #include "webaddr.h" //#include "ccobject.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "pathname.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "resimmap.h" DECLARE_SOURCE("$Revision: 1282 $"); CC_IMPLEMENT_DYNAMIC(WebAddress, CCObject) /********************************************************************************************** > WebAddress::WebAddress() Author: Graham_Walmsley (Xara Group Ltd) Created: 17/9/96 Inputs: None Outputs: None Returns: None Purpose: Default WebAddress class constructor Errors: None **********************************************************************************************/ WebAddress::WebAddress() { Absolute = FALSE; } /********************************************************************************************** > WebAddress::WebAddress(const WebAddress& newPath) Author: Graham_Walmsley (Xara Group Ltd) Created: 17/9/96 Inputs: InAddress Outputs: None Returns: None Purpose: Copy Constructor for the WebAddress class Errors: None **********************************************************************************************/ WebAddress::WebAddress(const WebAddress& InAddress) { Absolute = InAddress.Absolute; Scheme=InAddress.Scheme; NetLoc=InAddress.NetLoc; Path=InAddress.Path; Parameters=InAddress.Parameters; Query=InAddress.Query; Fragment=InAddress.Fragment; } /********************************************************************************************** > WebAddress& WebAddress::operator=(const WebAddress& InAddress) Author: Graham_Walmsley (Xara Group Ltd) Created: 17/9/96 Inputs: InAddress Outputs: None Returns: None Purpose: Assignment operator Errors: None **********************************************************************************************/ WebAddress& WebAddress::operator=(const WebAddress& InAddress) { Absolute = InAddress.Absolute; Scheme=InAddress.Scheme; NetLoc=InAddress.NetLoc; Path=InAddress.Path; Parameters=InAddress.Parameters; Query=InAddress.Query; Fragment=InAddress.Fragment; return *this; } /********************************************************************************************** > WebAddress::WebAddress(const String_256&, WebCorrectFlags wcfToUse=WebCorrectFlags()) Author: Graham_Walmsley (Xara Group Ltd) Created: 17/9/96 Inputs: StringToParse String representing the path. wcfToUse Flags indicating how the string should be corrected before it is parsed. Some options are: www.xara.com should be corrected to http://www.xara.com/, d:\dir1\filename.gif should be corrected to file://d|/dir1/filename.gif. Outputs: None Returns: None Purpose: Corrects the string, then parses the corrected string. SeeAlso: WebCorrectFlags **********************************************************************************************/ WebAddress::WebAddress(const String_256& StringToParse, WebCorrectFlags wcfToUse) { //First make a copy of the string we've been given String_256 strCopy=StringToParse; //And correct the copy Correct(&strCopy, wcfToUse); //Then parse the corrected string Parse(strCopy); //And finally set the class's flags SetFlags(); } /********************************************************************************************** > INT32 WebAddress::operator==(WebAddress& Other) Author: Graham_Walmsley (Xara Group Ltd) Created: 10/6/97 Inputs: - Outputs: - Returns: - Purpose: Equality operator SeeAlso: WebCorrectFlags **********************************************************************************************/ INT32 WebAddress::operator==(WebAddress& Other) { return (Scheme==Other.Scheme && NetLoc==Other.NetLoc && Path==Other.Path && Parameters==Other.Parameters && Query==Other.Query && Fragment==Other.Fragment); } /********************************************************************************************** > WebAddress::Parse() Author: Graham_Walmsley (Xara Group Ltd) Created: 1/9/96 Inputs: String representing the full URL Outputs: None Returns: None Purpose: Takes the string and splits it into its component parts. Notes: The parsing rules follow the guidelines given in http://ds.internic.net/rfc/rfc1808.txt. So there! (That means, don't change them unless you know what you're doing). These rules can be pretty unforgiving...if you get the query, fragment and parameters in the wrong order, the parsing rules don't accommodate this. But I'm sticking with the rules because of funny things like... a query could, theoretically, have a # in the middle of it. Note that this parsing function should split InString into several different strings and put those strings into member variables, but it should not change the actual text of InString. In other words, if you concatenate the following member variables: Scheme+NetLoc+Path+Parameters+Query+Fragment You should *always* end up with the string InString you passed into the function. *Please* don't change the parsing rules unless you really know what you're doing and have read the guideline document referred to above. The parsing that is performed below may look easy, but it is performed by qualified professionals and is extremely dangerous. Do not imitate the parsing that you see below at home. **********************************************************************************************/ BOOL WebAddress::Parse(const String_256& InString) { //First set all the member strings to zero. Absolute=FALSE; Scheme.Empty(); NetLoc.Empty(); Path.Empty(); Parameters.Empty(); Query.Empty(); Fragment.Empty(); Scheme.Empty(); //If InString="", that's all we need to do... if (InString.IsEmpty()) return TRUE; //And set up a couple of strings we can play around with String_256 StringToParse=InString; //If the parse string is empty, we need do nothing, because all our fields are //already blank. Return TRUE. if (StringToParse.IsEmpty()) return TRUE; //Now set up some strings. These are all hard coded cos it reduces code size //This shouldn't matter for purposes of internationalisation, because URLs //are an international system. String_256 sNetloc="//"; // INT32 iLowerCaseA=INT32 ('a'); // INT32 iLowerCaseZ=INT32 ('z'); // INT32 iUpperCaseA=INT32 ('A'); // INT32 iUpperCaseZ=INT32 ('Z'); // char cBackslash='\\'; char cSlash='/'; char cHash='#'; char cColon=':'; char cQuestionmark='?'; char cSemicolon=';'; //First we want to find the Fragment section of the URL. //This should start with a # INT32 iFound=StringToParse.FindNextChar(cHash); //If we've found a #, copy the whole identifier into the "fragment" member variable if(iFound>=0) StringToParse.Split(&StringToParse, &Fragment, iFound, FALSE); //Now search the parse string for a scheme (the bit at the start, //e.g. http:). To do this we search for a colon. iFound=StringToParse.FindNextChar(cColon); //Have we found a colon? if(iFound>=0) { BOOL IsAScheme=TRUE; //Yes. We now need to check that everything before that colon is a letter. for (INT32 iStringPtr=(iFound-1); iStringPtr>=0; iStringPtr--) { if (!StringBase::IsAlpha(StringToParse[iStringPtr])) { IsAScheme=FALSE; } } //Was everything before the colon a letter? if (IsAScheme) //Yes, so split the string after that colon StringToParse.Split(&Scheme, &StringToParse, iFound, TRUE); } //Now look for a network location iFound=StringToParse.Sub(sNetloc); //Have we found a //? if(iFound>=0) { //Yes. So find the next / (or the end of the string) //To do this, set up a string pointer that starts from two //characters after iFound INT32 iStringPtr=iFound+2; //And move that string pointer forwards until //either it points at a slash or it reaches the end of the //string while (iStringPtr=0) StringToParse.Split(&StringToParse, &Query, iFound,FALSE); //Now look for parameter information. iFound=StringToParse.FindNextChar(cSemicolon); //Have we found a semicolon? if(iFound>=0) StringToParse.Split(&StringToParse, &Parameters, iFound, FALSE); //And whatever is left is the path. Path=StringToParse; return TRUE; } /********************************************************************************************** > void WebAddress::SetFlags() Author: Graham_Walmsley (Xara Group Ltd) Created: 17/9/96 Purpose: Sets the Web Address flags - at the moment the only flag is Absolute - by looking at the Web Address string member variables. **********************************************************************************************/ BOOL WebAddress::SetFlags() { Absolute=!Scheme.IsEmpty(); return TRUE; } /********************************************************************************************** > void WebAddress::Combine(WebAddress Base) Author: Graham_Walmsley (Xara Group Ltd) Created: 17/9/96 Inputs: A Base URL Purpose: Combines this Web Address with a base Web Address. This is used when this Web Address is relative and the base web address is the address of the current document. This function allows this Web Address to inherit the appropriate components of the base address so this Address becomes relative. This is quite hard to explain, so here's an example: if this Web address is "myfile.xar" and the base Web Address is "http://www.xara.com/currentfile.xar" then this function makes this Web Address into "http://www.xara.com/myfile.xar". This function follows the guidelines given in some international standard somewhere. (The one I was talking about above) Because it follows these guidelines (almost) exactly, this function contains one hell of a lot of loops within loops. Sorry! I've tried to comment them helpfully. Notes: The parsing rules follow the guidelines given in http://ds,internic.net/rfc/rfc1808.txt. *Please* don't change the parsing rules unless you really know what you're doing and have read the guideline document referred to above. The code below is written according to that document. Do not imitate at home what you have seen on Gladiators, etc, etc. **********************************************************************************************/ void WebAddress::Combine(WebAddress Base) { //Strings are hard coded to reduce code size String_256 sSlashDotSlash="/./"; String_256 sSlashDotDotSlash="/../"; TCHAR cSlash='/'; //Now start the parsing. //If the base Web Address is empty, this Web Address does not change if (Base.IsEmpty()) goto ReturnNow; //If this Web Address is empty, then it inherits everything from the //base Web Address if (IsEmpty()) { Absolute = Base.Absolute; Scheme=Base.Scheme; NetLoc=Base.NetLoc; Path=Base.Path; Parameters=Base.Parameters; Query=Base.Query; Fragment=Base.Fragment; goto ReturnNow; } //If this Web Address is absolute, it does not change if (IsAbsolute()) goto ReturnNow; //If none of the above apply, this Web Address inherits the scheme of //the Base address Scheme=Base.Scheme; //If this Web Address has a net location, we need do nothing more to it. if (!NetLoc.IsEmpty()) goto ReturnNow; //Otherwise, this Web Address inherits the Net Location of the base address. NetLoc=Base.NetLoc; //If the path of this Web Address starts with a slash, it is non-relative //and we need only add it on to the Net Location if ((*(Path))==cSlash) goto ReturnNow; //This is where all the loops within loops start. Hang on to your curly brackets. //Does this Web Address have a path? if (!Path.IsEmpty()) { //Yes. Then the full path is given by: //The Base URL path up to the rightmost slash + the URL of this Web Address //This string will hold the base URL path up to the rightmost slash String_256 sTempPath=""; //First find the rightmost slash in Base.Path INT32 iFound=Base.Path.ReverseFind(cSlash); //Did we find a slash? if (iFound>=0) { //Yes. So copy everything up to that slash into sTempPath Base.Path.Split(&sTempPath, NULL, iFound, TRUE); sTempPath+=Path; Path=sTempPath; }//End IF there's a slash in Base.Path //We now need to check the path for ../ and ./ //First let's search for /./ iFound=Path.Sub(sSlashDotSlash); //If we've found a /./ while (iFound>=0) { //Then remove the ./ part of it. Path.Remove(iFound+1, 2); //And look for the next /./ to remove iFound=Path.Sub(sSlashDotSlash); } //Now we want to remove all occurrences of /[path segment/../ //So first let's do a search for /../ iFound=Path.Sub(sSlashDotDotSlash); //If we've found a /./ while (iFound>=0) { //Then go back until we find the start of the path segment before it INT32 iStartOfSection=iFound-1; while (iStartOfSection>=0 && Path[iStartOfSection]!=cSlash) iStartOfSection--; if (iStartOfSection>=0) { //Get iStartOfSection to represent the character after the slash, //rather than the slash iStartOfSection++; //So if we've found something, then set a pointer to the end of that //section INT32 iEndOfSection=iFound+3; Path.Remove(iStartOfSection, (iEndOfSection-iStartOfSection+1)); } else //If we found an unparsable /../, then break now before we //get into trouble... break; //And find the next /../ iFound=Path.Sub(sSlashDotDotSlash); } } else { //No, this Web Address doesn't have a path. //So it inherits the path of the base URL. Path=Base.Path; //If this Web Address has some parameters, we need do nothin more to it if (!Parameters.IsEmpty()) goto ReturnNow; //Otherwise this Web Address inherits the parameters of the base URL Parameters=Base.Parameters; //If this Web Address has a query, we need do nothin more to it if (!Query.IsEmpty()) goto ReturnNow; //Otherwise this Web Address inherits the parameters of the base URL Query=Base.Query; //And that's it. (Fragments are never inherited). //So we can return. goto ReturnNow; }//End if (!Path.IsEmpty()) else... ReturnNow: //Set the "Absolute" flag to whatever it's meant to be, and return SetFlags(); return; } /********************************************************************************************** > String_256 WebAddress::GetWebAddress() Author: Graham_Walmsley (Xara Group Ltd) Created: 17/9/96 Inputs: - Returns: The full URL string Purpose: Returns the URL string **********************************************************************************************/ String_256 WebAddress::GetWebAddress() { String_256 strToReturn=Scheme; strToReturn+=NetLoc; strToReturn+=Path; strToReturn+=Parameters; strToReturn+=Query; strToReturn+=Fragment; return strToReturn; } /********************************************************************************************** > BOOL WebAddress::IsHTTP() Author: Graham_Walmsley (Xara Group Ltd) Created: 17/9/96 Inputs: - Returns: TRUE if this Web Address starts with HTTP Purpose: Finds whether this Web Address starts with "HTTP:" **********************************************************************************************/ BOOL WebAddress::IsHTTP() const { return (Scheme.SubWithoutCase(String_256(_R(IDS_URL_HTTPCOLON)))==0); } /********************************************************************************************** > BOOL WebAddress::IsValidHTTP() Author: Graham_Walmsley (Xara Group Ltd) Created: 27/6/97 Inputs: - Returns: TRUE if this Web Address starts with HTTP and has a net location Purpose: Finds whether this Web Address is a valid HTTP address. We say it's a valid HTTP address if: a. It starts with HTTP b. It has a net location Note that a valid http address may be valid but refer to a non-existent network location - for example: http://nonsensenonsense is a valid HTTP URL that refers to a server called "nonsensenonsense", which does not exist. **********************************************************************************************/ BOOL WebAddress::IsValidHTTP() const { return (IsHTTP() && !NetLocIsEmpty()); } /********************************************************************************************** > static BOOL WebAddress::IsHTTP(const String_256& strTest) Author: Graham_Walmsley (Xara Group Ltd) Created: 17/9/96 Inputs: - Returns: TRUE if strTest starts with HTTP Purpose: Finds whether strTest starts with "HTTP:" **********************************************************************************************/ BOOL WebAddress::IsHTTP(const String_256& strTest) { WebAddress urlTest(strTest); return (urlTest.IsHTTP()); } /******************************************************************************************** BOOL WebAddress::IsLocalFile() Author: Graham_Walmsley (Xara Group Ltd) Created: 10/6/97 Inputs: - Outputs: - Returns: TRUE if we consider pstrCorrect to be a local filename FALSE otherwise Purpose: Works out if we consider this Web Address to be a local filename. It's a local filename if its scheme is "file:" Errors: - SeeAlso: WebAddress::GetPathName() ********************************************************************************************/ BOOL WebAddress::IsLocalFile() const { return( Scheme == wxT("file:") ); } /******************************************************************************************** PathName WebAddress::GetPathName() Author: Graham_Walmsley (Xara Group Ltd) Created: 10/6/97 Inputs: - Outputs: - Returns: The PathName that is equivalent to this URL. Purpose: This is used to convert a local file URL (that is, a URL whose scheme is "file:") to a pathname. Before calling this function, call "IsLocalFile()" to make sure the scheme is "file:". For example, this function converts: file://d|/dir1/file.htm to d:\dir1\file.htm file:////Netloc/dir1/file.htm to \\Netloc\dir1\file.htm It also converts the following URLs correctly. Note that these URLs are illegal - but they appear in the IE3 URL bar! file://d:\dir1\file.htm to d:\dir1\file.htm file://\\netloc\dir1\file.htm to \\netloc\dir1\file.htm It does this as follows: 1. First, the "file:" part is removed 2. Then, if the net location starts with "//", that "//" is removed. 3. All forward slashes are converted to backslashes 4. All "|" characters are converted to colons Of course there's no guarantee that what's left is a valid path name. Errors: - SeeAlso: WebAddress::IsLocalFile() ********************************************************************************************/ PathName WebAddress::GetPathName() const { //We needn't actually do anything to remove the Scheme - we just don't //use it //First concatenate the net location and the path String_256 strToReturn=NetLoc; strToReturn+=Path; //So, does that string start with "//"? if (strToReturn.Sub(String_256("//"))==0) { //Yes. So remove it strToReturn.Split(NULL, &strToReturn, 1, TRUE); } //Convert all forward slashes to backslashes strToReturn.SwapChar('/', '\\'); //Convert all | characters to colons strToReturn.SwapChar('|', ':'); //Put our string into a PathName object PathName pthToReturn(strToReturn); //And return it return pthToReturn; } /******************************************************************************************** WebAddress correction functions These functions correct the URL. For example, www.xara.com might be corrected to http://www.xara.com/ ********************************************************************************************/ /******************************************************************************************** void WebAddress::Correct(String_256* pstrCorrect, WebCorrectFlags wcfToUse) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to correct wcfToUse - a set of flags which detail how to correct the string Outputs: pstrCorrect - the corrected string Returns: - Purpose: Corrects the URL string that the user has entered, according to the correction flags. Errors: - SeeAlso: WebAddress::ApplyWebAddressToSelection; WebCorrectFlags ********************************************************************************************/ void WebAddress::Correct(String_256* pstrCorrect, WebCorrectFlags wcfToUse) { //If we should be correcting backslashes to forward slashes, do so now if (wcfToUse.CorrectBackslashes()) CorrectBackslashes(pstrCorrect); //If we should be correcting local filenames if (wcfToUse.CorrectLocalFilenames() && ShouldCorrectLocalFilenames(pstrCorrect)) { //Then correct it to a URL pointing to a local filename CorrectLocalFilenames(pstrCorrect); } //Now, if we should be correcting Netscape local URLs to IE3 ones if (wcfToUse.CorrectNetscapeFilenames() && ShouldCorrectNetscapeFilenames(pstrCorrect)) { //Then correct it CorrectNetscapeFilenames(pstrCorrect); } //Otherwise if we should be correcting ftp addresses else if (wcfToUse.CorrectFTP() && ShouldCorrectFTP(pstrCorrect)) { //Then add "ftp:" to the front CorrectFTP(pstrCorrect); } //Otherwise if we should be adding http:// to the front else if (wcfToUse.CorrectHTTP() && ShouldCorrectHTTP(pstrCorrect)) { //Then add "http://" to the front CorrectHTTP(pstrCorrect); } //Otherwise if the string contains an @ else if (ShouldCorrectMailto(pstrCorrect)) { //Then add "mailto:" to the front CorrectMailto(pstrCorrect); } //If we should be ensuring that http addresses have a net location if (wcfToUse.CorrectNoNetLoc() && ShouldCorrectNoNetLoc(pstrCorrect)) { //Then add a slash to the end CorrectNoNetLoc(pstrCorrect); } //And finally, if we should be adding a slash to the end if (wcfToUse.CorrectNoSlash() && ShouldCorrectNoSlash(pstrCorrect)) { //Then add a slash to the end CorrectNoSlash(pstrCorrect); } } /******************************************************************************************** void WebAddress::CorrectBackslashes(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to correct Outputs: pstrCorrect - the corrected string Returns: - Purpose: Corrects any backslashes in the entered string to slashes Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ void WebAddress::CorrectBackslashes(String_256* pstrCorrect) { //Check our parameter if (pstrCorrect==NULL) { ERROR2RAW("WebAddress::CorrectBackslashes - NULL parameter"); return; } //And correct all backslashes to forward slashes pstrCorrect->SwapChar('\\', '/'); } /******************************************************************************************** BOOL WebAddress::ShouldCorrectLocalFilenames(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to test Outputs: - Returns: TRUE if we consider pstrCorrect to be a local filename FALSE otherwise Purpose: Works out if we consider this string to be a local filename. We consider this to be a local filename if a. It begins with a letter followed by a colon b. It begins with \\, in which case it is a UNC pathname Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ BOOL WebAddress::ShouldCorrectLocalFilenames(String_256* pstrCorrect) { //Check our parameter ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectBackslash - NULL parameter"); //If the length of the string is less than two characters, return FALSE if (pstrCorrect->Length()<2) return FALSE; //Now, if the first character is a letter and the second character is a //colon, return TRUE if (StringBase::IsAlpha((*pstrCorrect)[0]) && (*pstrCorrect)[1]==':') { return TRUE; } //Otherwise, if the first two characters are forward slashes, return TRUE if ((*pstrCorrect)[0]=='/' && (*pstrCorrect)[1]=='/') { return TRUE; } //Otherwise return FALSE return FALSE; } /******************************************************************************************** void WebAddress::CorrectLocalFilenames(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to correct Outputs: pstrCorrect - the corrected string Returns: - Purpose: Assumes pstrCorrect is a local filename, then converts it to a URL referring to a local filename. It does this by calling the function PathName::GetWebAddress() Errors: - SeeAlso: WebAddress::Correct(), PathName::GetWebAddress() ********************************************************************************************/ void WebAddress::CorrectLocalFilenames(String_256* pstrCorrect) { //Check our parameter if(pstrCorrect==NULL) { ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter"); return; } //Now, create a pathname out of our string PathName pthTemp=*pstrCorrect; //And call the GetWebAddress function *pstrCorrect=pthTemp.GetWebAddress(); } /******************************************************************************************** BOOL WebAddress::ShouldCorrectNetscapeFilenames(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 25/6/97 Inputs: pstrCorrect - the string to test Outputs: - Returns: TRUE if we consider pstrCorrect to be a Netscape local filename. FALSE otherwise Purpose: Works out if we consider this string to be a Netscape local filename. We consider this to be a Netscape local filename if it begins with "file:///", but does not begin with "file:////". The problem here is that Netscape refers to local filenames as follows: file:///d|/dir1/myname.htm But IE3 refers to local filenames as: file://d|/dir1/myname.htm Note the difference in the number of slashes. We correct it to the IE3 version. Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ BOOL WebAddress::ShouldCorrectNetscapeFilenames(String_256* pstrCorrect) { //Check our parameter ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectNetscapeFilenames - NULL parameter"); //Set up some strings to search for String_256 strThreeSlashes("file:///"); String_256 strFourSlashes("file:////"); //Now, if the string begins with "file:///"... if (pstrCorrect->SubWithoutCase(strThreeSlashes)==0) { //But the string doesn't begin with "file:////" if (pstrCorrect->SubWithoutCase(strFourSlashes)!=0) //Then we shoul correct it return TRUE; } //Otherwise return FALSE return FALSE; } /******************************************************************************************** void WebAddress::CorrectNetscapeFilenames(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to correct Outputs: pstrCorrect - the corrected string Returns: - Purpose: Converts a Netscape local filename (file:///xxxxxxx) to an IE3 local filename (file://xxxxxxx) by simply removing the third slash. Errors: - SeeAlso: WebAddress::Correct(), PathName::GetWebAddress() ********************************************************************************************/ void WebAddress::CorrectNetscapeFilenames(String_256* pstrCorrect) { //Check our parameter if(pstrCorrect==NULL) { ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter"); return; } //Simply delete the fifth character, removing one of the slashes pstrCorrect->Remove(6, 1); } /******************************************************************************************** BOOL WebAddress::ShouldCorrectFTP(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to test Outputs: - Returns: TRUE if we consider pstrCorrect to be an ftp address FALSE otherwise Purpose: Works out if we consider this string to be a ftp address with the "ftp:" missing. We do so if the string starts "ftp.". Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ BOOL WebAddress::ShouldCorrectFTP(String_256* pstrCorrect) { //Check our parameter ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectBackslash - NULL parameter"); //Are the first four characters "ftp." ? if (pstrCorrect->SubWithoutCase(String_256("ftp."))==0) return TRUE; //Otherwise return FALSE return FALSE; } /******************************************************************************************** void WebAddress::CorrectFTP(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to correct Outputs: pstrCorrect - the corrected string Returns: - Purpose: Puts "ftp:" on the start of pstrCorrect. Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ void WebAddress::CorrectFTP(String_256* pstrCorrect) { //Check our parameter if(pstrCorrect==NULL) { ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter"); return; } //If our string is over two hundred and fifty characters long, return if (pstrCorrect->Length()>250) return; //Otherwise, create a new string containing "ftp://" String_256 strToReturn="ftp://"; //Add our other string onto the end of it strToReturn+=*pstrCorrect; //And copy our new string into our old string *pstrCorrect=strToReturn; } /******************************************************************************************** BOOL WebAddress::ShouldCorrectHTTP(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to test Outputs: - Returns: TRUE if we consider pstrCorrect to be an http address FALSE otherwise Purpose: Works out if we consider this string to be a http address with the "http:" missing. We do so if the string starts with a string of the following characters: ;?:&=%$-_.+!*'(),abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 ...which contains at least two full stops. (This string of characters is taken from http://ds.internic.net/rfc/rfc1808.txt, page 4, but altered slightly). The first character should not be a full stop and there should not be two full stops together. For example: abc-def12.gh4i3.jkl.mno Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ BOOL WebAddress::ShouldCorrectHTTP(String_256* pstrCorrect) { //Check our parameter ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectBackslash - NULL parameter"); //Get the length of the string INT32 iLength=pstrCorrect->Length(); //If the string is empty, return FALSE if (iLength<=0) return FALSE; //Now, here is the set of characters to test for TCHAR *strAllowed = _T(";?&=%abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$-_.+!*'(),"); //If the first character is a full stop, return FALSE if ((*pstrCorrect)[0]=='.') return FALSE; //And this variable will keep a count of the number of full stops INT32 iFullStops=0; //This variable will tell us if the last character we looked at //was a full stop BOOL fLastCharWasFullStop=FALSE; //Now, starting at the first character in the string, scan through //each character in turn until we get to something that is not //in our set of allowed characters for (INT32 i=0; i=2); } /******************************************************************************************** void WebAddress::CorrectHTTP(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to correct Outputs: pstrCorrect - the corrected string Returns: - Purpose: Puts "http:" on the start of pstrCorrect. Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ void WebAddress::CorrectHTTP(String_256* pstrCorrect) { //Check our parameter if(pstrCorrect==NULL) { ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter"); return; } //If our string is over two hundred and fifty characters long, return if (pstrCorrect->Length()>250) return; //Otherwise, create a new string containing "http:" String_256 strToReturn="http://"; //Add our other string onto the end of it strToReturn+=*pstrCorrect; //And copy our new string into our old string *pstrCorrect=strToReturn; } /******************************************************************************************** BOOL WebAddress::ShouldCorrectNoSlash(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to test Outputs: - Returns: TRUE if we consider that pstrCorrect is a URL to which the user has forgotten to add a trailing slash FALSE otherwise Purpose: Works out if we consider this string to be a URL with a trailing slash missing. We do this by creating a Web Address object to parse the string. (Note that if this function is called, then the URL will already have had an "http://" added to the front if necessary). Then we consider that the URL should have a slash added if a. The string consists of a net location but no path (e.g. "http://www.xara.com", which should become "http://www.xara.com/") b. The path portion of the URL does not end in a slash, and the final segment of the path does not have a full stop character in it. That is, "http://www.bbc.co.uk/radio1" should have a slash added on the end, but "http://www.bbc.co.uk/index.htm" should not. Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ BOOL WebAddress::ShouldCorrectNoSlash(String_256* pstrCorrect) { //Check our parameter ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectNoSlash - NULL parameter"); //First create a Web Address from our string WebAddress urlTest(*pstrCorrect); //Now, does the Web Address start with HTTP:, and does it have a net location //specified? if (urlTest.IsHTTP() && !urlTest.NetLocIsEmpty()) { //Yes. //So, does the Web Address have an empty path? if (urlTest.PathIsEmpty()) { //Yes. So we should add a slash to it. return TRUE; } else { //No, there is something in the path. //So, does the path end in something other than a slash? INT32 iLength=urlTest.Path.Length(); if (urlTest.Path[iLength-1]!='/') { //Yes. So we should add a slash only if //the last segment of the path does not contain a full stop. //First try and find a slash in the path string, starting //from the end INT32 iSlashFound=urlTest.Path.ReverseFind('/'); //Now try and find a full stop in the path string, starting //from the end INT32 iFullStopFound=urlTest.Path.ReverseFind('.'); //Now... //If we didn't find a full stop, we should add a slash if (iFullStopFound==-1) return TRUE; //Otherwise, we should only add a slash if the slash //was found after the full stop if (iSlashFound>iFullStopFound) return TRUE; //Otherwise, we don't add a slash } } } //So, none of our conditions were met. //So we don't add a slash return FALSE; } /******************************************************************************************** void WebAddress::CorrectNoSlash(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to correct Outputs: pstrCorrect - the corrected string Returns: - Purpose: Adds a slash to the end of the string Errors: - SeeAlso: WebAddress::Correct(); WebAddress::ShouldCorrectNoSlash() ********************************************************************************************/ void WebAddress::CorrectNoSlash(String_256* pstrCorrect) { //Check our parameter if(pstrCorrect==NULL) { ERROR2RAW("WebAddress::CorrectNoSlash - NULL parameter"); return; } //And if the string is long enough if (pstrCorrect->Length()<255) { //Add a slash to the end *pstrCorrect+='/'; } } /******************************************************************************************** BOOL WebAddress::ShouldCorrectMailto(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to test Outputs: - Returns: TRUE if we consider pstrCorrect to be a mail address FALSE otherwise Purpose: Works out if we consider this string to be a mail address with the "mailto:" missing. We do so if it contains an @ character and does not contain a colon Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ BOOL WebAddress::ShouldCorrectMailto(String_256* pstrCorrect) { //Check our parameter ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectBackslash - NULL parameter"); //Find the first @ symbol INT32 iLocationOfAtSymbol=pstrCorrect->FindNextChar('@'); //If we found one if (iLocationOfAtSymbol>0) { //Then check for a colon INT32 iLocationOfColon=pstrCorrect->FindNextChar(':'); //If we didn't find one, return TRUE if (iLocationOfColon<0) return TRUE; } return FALSE; } /******************************************************************************************** void WebAddress::CorrectMailto(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to correct Outputs: pstrCorrect - the corrected string Returns: - Purpose: Puts "mailto:" on the start of pstrCorrect. Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ void WebAddress::CorrectMailto(String_256* pstrCorrect) { //Check our parameter if(pstrCorrect==NULL) { ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter"); return; } //If our string is over two hundred and fifty characters long, return if (pstrCorrect->Length()>250) return; //Otherwise, create a new string containing "mailto:" String_256 strToReturn="mailto:"; //Add our other string onto the end of it strToReturn+=*pstrCorrect; //And copy our new string into our old string *pstrCorrect=strToReturn; } /******************************************************************************************** BOOL WebAddress::ShouldCorrectNoNetLoc(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 27/6/97 Inputs: pstrCorrect - the string to test Outputs: - Returns: TRUE if pstrCorrect starts with "http" but does not have "//" afterwards to signify a net location FALSE otherwise Purpose: Works out if we consider this string to be an HTTP address with the "//" to signify a network location missing. For example: http:www.xara.com Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ BOOL WebAddress::ShouldCorrectNoNetLoc(String_256* pstrCorrect) { //Check our parameter ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectBackslash - NULL parameter"); //Return TRUE if the string starts with "http:" but doesn't start with "http://" String_256 strHTTP("http:"); String_256 strHTTPSlashSlash("http://"); return (pstrCorrect->SubWithoutCase(strHTTP)==0 && pstrCorrect->SubWithoutCase(strHTTPSlashSlash)!=0); } /******************************************************************************************** void WebAddress::CorrectNoNetLoc(String_256* pstrCorrect) Author: Graham_Walmsley (Xara Group Ltd) Created: 28/5/97 Inputs: pstrCorrect - the string to correct Outputs: pstrCorrect - the corrected string Returns: - Purpose: Ensures that pstrCorrect starts with "http://" Errors: - SeeAlso: WebAddress::Correct() ********************************************************************************************/ void WebAddress::CorrectNoNetLoc(String_256* pstrCorrect) { //Check our parameter if(pstrCorrect==NULL) { ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter"); return; } //We already know that our string does not start with "http://" //But does it start with "http:/"? if (pstrCorrect->SubWithoutCase(String_256("http:/"))==0) { //Yes it does. So insert an extra slash pstrCorrect->Insert( String_256("/"), 5 ); } else { //No it doesn't. So insert an extra two slashes after the HTTP pstrCorrect->Insert( String_256("//"), 5 ); } }