webaddr.cpp

Go to the documentation of this file.
00001 // $Id: webaddr.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099                     
00100 #include "camtypes.h"
00101 #include "webaddr.h"
00102 
00103 //#include "ccobject.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00104 //#include "pathname.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00105 
00106 //#include "resimmap.h"
00107     
00108 DECLARE_SOURCE("$Revision: 1282 $");
00109 
00110 CC_IMPLEMENT_DYNAMIC(WebAddress, CCObject)
00111 
00112 /**********************************************************************************************
00113 
00114 >   WebAddress::WebAddress()
00115 
00116     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00117     Created:    17/9/96
00118     Inputs:     None
00119     Outputs:    None
00120     Returns:    None
00121     Purpose:    Default WebAddress class constructor
00122     Errors:     None
00123 
00124 **********************************************************************************************/
00125 
00126 WebAddress::WebAddress()
00127 {
00128     Absolute = FALSE;
00129 }
00130 
00131 /**********************************************************************************************
00132 
00133 >   WebAddress::WebAddress(const WebAddress& newPath)
00134 
00135     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00136     Created:    17/9/96
00137     Inputs:     InAddress
00138     Outputs:    None
00139     Returns:    None
00140     Purpose:    Copy Constructor for the WebAddress class
00141     Errors:     None
00142 
00143 **********************************************************************************************/
00144 
00145 WebAddress::WebAddress(const WebAddress& InAddress)
00146 {
00147     Absolute = InAddress.Absolute;
00148 
00149     Scheme=InAddress.Scheme;
00150     NetLoc=InAddress.NetLoc;
00151     Path=InAddress.Path;
00152     Parameters=InAddress.Parameters;
00153     Query=InAddress.Query;                    
00154     Fragment=InAddress.Fragment;
00155 }
00156 
00157 /**********************************************************************************************
00158 
00159 >   WebAddress& WebAddress::operator=(const WebAddress& InAddress)
00160 
00161     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00162     Created:    17/9/96
00163     Inputs:     InAddress
00164     Outputs:    None
00165     Returns:    None
00166     Purpose:    Assignment operator
00167     Errors:     None
00168 
00169 **********************************************************************************************/
00170 
00171 WebAddress& WebAddress::operator=(const WebAddress& InAddress)
00172 {
00173     Absolute = InAddress.Absolute;
00174 
00175     Scheme=InAddress.Scheme;
00176     NetLoc=InAddress.NetLoc;
00177     Path=InAddress.Path;
00178     Parameters=InAddress.Parameters;
00179     Query=InAddress.Query;                    
00180     Fragment=InAddress.Fragment;
00181 
00182     return *this;
00183 }
00184 
00185 /**********************************************************************************************
00186 
00187 >   WebAddress::WebAddress(const String_256&, WebCorrectFlags wcfToUse=WebCorrectFlags())
00188 
00189     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00190     Created:    17/9/96
00191     Inputs:     StringToParse    String representing the path.
00192                 wcfToUse         Flags indicating how the string should be
00193                                  corrected before it is parsed. Some options
00194                                  are: www.xara.com should be corrected to 
00195                                  http://www.xara.com/, d:\dir1\filename.gif
00196                                  should be corrected to file://d|/dir1/filename.gif.
00197 
00198     Outputs:    None
00199     Returns:    None
00200     Purpose:    Corrects the string, then parses the corrected string.
00201     SeeAlso:    WebCorrectFlags
00202 
00203 **********************************************************************************************/
00204 
00205 WebAddress::WebAddress(const String_256& StringToParse, WebCorrectFlags wcfToUse)
00206 {
00207     //First make a copy of the string we've been given
00208     String_256 strCopy=StringToParse;
00209 
00210     //And correct the copy
00211     Correct(&strCopy, wcfToUse);
00212 
00213     //Then parse the corrected string
00214     Parse(strCopy);
00215 
00216     //And finally set the class's flags
00217     SetFlags();
00218 }
00219 
00220 /**********************************************************************************************
00221 
00222 >   INT32 WebAddress::operator==(WebAddress& Other)
00223 
00224     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00225     Created:    10/6/97
00226     Inputs:     -
00227 
00228     Outputs:    -
00229     Returns:    -
00230     Purpose:    Equality operator
00231     SeeAlso:    WebCorrectFlags
00232 
00233 **********************************************************************************************/
00234 
00235 INT32 WebAddress::operator==(WebAddress& Other)
00236 {
00237     return (Scheme==Other.Scheme &&
00238         NetLoc==Other.NetLoc &&
00239         Path==Other.Path &&
00240         Parameters==Other.Parameters &&
00241         Query==Other.Query &&
00242         Fragment==Other.Fragment);
00243 }
00244 
00245 
00246 
00247 /**********************************************************************************************
00248 
00249 >   WebAddress::Parse()
00250 
00251     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00252     Created:    1/9/96
00253     Inputs:     String representing the full URL
00254     Outputs:    None
00255     Returns:    None
00256     Purpose:    Takes the string and splits it into its component parts.
00257 
00258     Notes:      The parsing rules follow the guidelines given in 
00259                 http://ds.internic.net/rfc/rfc1808.txt. So there! 
00260                 (That means, don't change them unless you know what you're doing).
00261 
00262                 These rules can be pretty unforgiving...if you get the query, fragment
00263                 and parameters in the wrong order, the parsing rules don't accommodate
00264                 this. But I'm sticking with the rules because of funny things like...
00265                 a query could, theoretically, have a # in the middle of it.
00266 
00267                 Note that this parsing function should split InString into
00268                 several different strings and put those strings into
00269                 member variables, but it should not change the actual text
00270                 of InString. 
00271                 
00272                 In other words, if you concatenate the following member
00273                 variables:
00274 
00275                 Scheme+NetLoc+Path+Parameters+Query+Fragment
00276 
00277                 You should *always* end up with the string InString you passed into
00278                 the function.
00279 
00280                 *Please* don't change the parsing rules unless you really know what
00281                 you're doing and have read the guideline document referred to above.
00282                 The parsing that is performed below may look easy, but it is
00283                 performed by qualified professionals and is extremely dangerous.
00284                 Do not imitate the parsing that you see below at home.
00285 
00286 **********************************************************************************************/
00287 
00288 BOOL WebAddress::Parse(const String_256& InString)
00289 {
00290     //First set all the member strings to zero.
00291     Absolute=FALSE;
00292 
00293     Scheme.Empty(); 
00294     NetLoc.Empty();
00295     Path.Empty();
00296     Parameters.Empty();
00297     Query.Empty();
00298     Fragment.Empty();
00299     Scheme.Empty();
00300 
00301     //If InString="", that's all we need to do...
00302     if (InString.IsEmpty())
00303         return TRUE;
00304 
00305     //And set up a couple of strings we can play around with
00306     String_256 StringToParse=InString;
00307 
00308     //If the parse string is empty, we need do nothing, because all our fields are 
00309     //already blank. Return TRUE.
00310 
00311     if (StringToParse.IsEmpty()) return TRUE;
00312 
00313     //Now set up some strings. These are all hard coded cos it reduces code size
00314     //This shouldn't matter for purposes of internationalisation, because URLs
00315     //are an international system.
00316     String_256 sNetloc="//";
00317         
00318 //  INT32 iLowerCaseA=INT32 ('a');
00319 //  INT32 iLowerCaseZ=INT32 ('z');
00320 //  INT32 iUpperCaseA=INT32 ('A');
00321 //  INT32 iUpperCaseZ=INT32 ('Z');
00322 
00323 //  char cBackslash='\\';
00324     char cSlash='/';
00325     char cHash='#';
00326     char cColon=':';
00327     char cQuestionmark='?';
00328     char cSemicolon=';';
00329     
00330     //First we want to find the Fragment section of the URL.
00331     //This should start with a #
00332     INT32 iFound=StringToParse.FindNextChar(cHash);
00333 
00334     //If we've found a #, copy the whole identifier into the "fragment" member variable
00335     if(iFound>=0)
00336         StringToParse.Split(&StringToParse, &Fragment, iFound, FALSE);
00337 
00338     //Now search the parse string for a scheme (the bit at the start,
00339     //e.g. http:). To do this we search for a colon.
00340     iFound=StringToParse.FindNextChar(cColon);
00341 
00342     //Have we found a colon?
00343     if(iFound>=0)
00344     {
00345         BOOL IsAScheme=TRUE;
00346 
00347         //Yes. We now need to check that everything before that colon is a letter.
00348         for (INT32 iStringPtr=(iFound-1); iStringPtr>=0; iStringPtr--)
00349         {
00350             if (!StringBase::IsAlpha(StringToParse[iStringPtr]))
00351             {
00352                 IsAScheme=FALSE;
00353             }
00354         }
00355 
00356                 
00357         //Was everything before the colon a letter?
00358         if (IsAScheme)
00359             //Yes, so split the string after that colon
00360             StringToParse.Split(&Scheme, &StringToParse, iFound, TRUE);
00361     }
00362 
00363     //Now look for a network location
00364     iFound=StringToParse.Sub(sNetloc);
00365 
00366     //Have we found a //?
00367     if(iFound>=0)
00368     {
00369         //Yes. So find the next / (or the end of the string)
00370         
00371         //To do this, set up a string pointer that starts from two
00372         //characters after iFound
00373         INT32 iStringPtr=iFound+2;
00374 
00375         //And move that string pointer forwards until
00376         //either it points at a slash or it reaches the end of the
00377         //string
00378         while (iStringPtr<StringToParse.Length() && StringToParse[iStringPtr]!=cSlash)
00379         {
00380             iStringPtr++;
00381         }
00382         
00383         StringToParse.Split(&NetLoc, &StringToParse, iStringPtr, FALSE);
00384     }
00385 
00386     //Now look for query information.
00387     iFound=StringToParse.FindNextChar(cQuestionmark);
00388         
00389     //Have we found a question mark?
00390     if(iFound>=0)
00391         StringToParse.Split(&StringToParse, &Query, iFound,FALSE);
00392     
00393 
00394     //Now look for parameter information.
00395     iFound=StringToParse.FindNextChar(cSemicolon);
00396 
00397     //Have we found a semicolon?
00398     if(iFound>=0)
00399         StringToParse.Split(&StringToParse, &Parameters, iFound, FALSE);
00400 
00401     //And whatever is left is the path.
00402     Path=StringToParse;
00403     
00404 
00405     return TRUE;
00406 }
00407 
00408 /**********************************************************************************************
00409 
00410 >   void WebAddress::SetFlags()
00411 
00412     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00413     Created:    17/9/96
00414     Purpose:    Sets the Web Address flags - at the moment the only flag is Absolute - by
00415                 looking at the Web Address string member variables.
00416 
00417 **********************************************************************************************/
00418 
00419 BOOL WebAddress::SetFlags()
00420 {
00421     Absolute=!Scheme.IsEmpty();
00422 
00423     return TRUE;
00424 }
00425 
00426 /**********************************************************************************************
00427 
00428 >   void WebAddress::Combine(WebAddress Base)
00429 
00430     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00431     Created:    17/9/96
00432     Inputs:     A Base URL
00433     Purpose:    Combines this Web Address with a base Web Address.
00434 
00435                 This is used when this Web Address is relative and the base
00436                 web address is the address of the current document. This function
00437                 allows this Web Address to inherit the appropriate components of the
00438                 base address so this Address becomes relative.
00439 
00440                 This is quite hard to explain, so here's an example: if this Web
00441                 address is "myfile.xar" and the base Web Address is 
00442                 "http://www.xara.com/currentfile.xar" then this function makes
00443                 this Web Address into "http://www.xara.com/myfile.xar".
00444 
00445                 This function follows the guidelines given in some international
00446                 standard somewhere. (The one I was talking about above)
00447 
00448                 Because it follows these guidelines (almost) exactly, this function
00449                 contains one hell of a lot of loops within loops. Sorry! I've tried
00450                 to comment them helpfully.
00451 
00452   Notes:        The parsing rules follow the guidelines given in 
00453                 http://ds,internic.net/rfc/rfc1808.txt.
00454 
00455                 *Please* don't change the parsing rules unless you really know what
00456                 you're doing and have read the guideline document referred to above.
00457                 The code below is written according to that document. Do not imitate
00458                 at home what you have seen on Gladiators, etc, etc.
00459 
00460 **********************************************************************************************/
00461 
00462 void WebAddress::Combine(WebAddress Base)
00463 {
00464     //Strings are hard coded to reduce code size
00465     String_256 sSlashDotSlash="/./";
00466     String_256 sSlashDotDotSlash="/../";
00467     
00468     TCHAR cSlash='/';
00469 
00470     //Now start the parsing.
00471 
00472     //If the base Web Address is empty, this Web Address does not change
00473     if (Base.IsEmpty())
00474         goto ReturnNow;
00475 
00476     //If this Web Address is empty, then it inherits everything from the 
00477     //base Web Address
00478     if (IsEmpty())
00479     {
00480         Absolute = Base.Absolute;
00481 
00482         Scheme=Base.Scheme;
00483         NetLoc=Base.NetLoc;
00484         Path=Base.Path;
00485         Parameters=Base.Parameters;
00486         Query=Base.Query;
00487         Fragment=Base.Fragment;
00488         goto ReturnNow;
00489     }
00490 
00491     //If this Web Address is absolute, it does not change
00492     if (IsAbsolute())
00493         goto ReturnNow;
00494 
00495     //If none of the above apply, this Web Address inherits the scheme of
00496     //the Base address
00497     Scheme=Base.Scheme;
00498 
00499     //If this Web Address has a net location, we need do nothing more to it.
00500     if (!NetLoc.IsEmpty())
00501         goto ReturnNow;
00502 
00503     //Otherwise, this Web Address inherits the Net Location of the base address.
00504     NetLoc=Base.NetLoc;
00505 
00506     //If the path of this Web Address starts with a slash, it is non-relative
00507     //and we need only add it on to the Net Location
00508     if ((*(Path))==cSlash) goto ReturnNow;
00509 
00510 
00511     //This is where all the loops within loops start. Hang on to your curly brackets.
00512 
00513     //Does this Web Address have a path?
00514     if (!Path.IsEmpty())
00515     {
00516         //Yes. Then the full path is given by:
00517         //The Base URL path up to the rightmost slash + the URL of this Web Address
00518         
00519         //This string will hold the base URL path up to the rightmost slash
00520         String_256 sTempPath="";
00521         
00522         //First find the rightmost slash in Base.Path
00523         INT32 iFound=Base.Path.ReverseFind(cSlash);
00524         
00525         //Did we find a slash?
00526         if (iFound>=0)
00527         {
00528             //Yes. So copy everything up to that slash into sTempPath
00529 
00530 
00531             Base.Path.Split(&sTempPath, NULL, iFound, TRUE);
00532             
00533             sTempPath+=Path;
00534 
00535             Path=sTempPath;
00536         }//End IF there's a slash in Base.Path
00537 
00538         
00539         //We now need to check the path for ../ and ./
00540         //First let's search for /./
00541         iFound=Path.Sub(sSlashDotSlash);
00542 
00543         //If we've found a /./
00544         while (iFound>=0)
00545         {
00546             //Then remove the ./ part of it.
00547             Path.Remove(iFound+1, 2);
00548 
00549             //And look for the next /./ to remove
00550             iFound=Path.Sub(sSlashDotSlash);
00551         }
00552 
00553         //Now we want to remove all occurrences of /[path segment/../
00554         //So first let's do a search for /../
00555         
00556         iFound=Path.Sub(sSlashDotDotSlash);
00557 
00558         //If we've found a /./
00559         while (iFound>=0)
00560         {
00561             //Then go back until we find the start of the path segment before it
00562             INT32 iStartOfSection=iFound-1;
00563 
00564             while (iStartOfSection>=0 && Path[iStartOfSection]!=cSlash)
00565                 iStartOfSection--;
00566 
00567             if (iStartOfSection>=0)
00568             {
00569                 //Get iStartOfSection to represent the character after the slash,
00570                 //rather than the slash
00571                 iStartOfSection++;
00572 
00573                 //So if we've found something, then set a pointer to the end of that
00574                 //section
00575                 INT32 iEndOfSection=iFound+3;
00576 
00577                 Path.Remove(iStartOfSection, (iEndOfSection-iStartOfSection+1));
00578             }
00579             else
00580                 //If we found an unparsable /../, then break now before we
00581                 //get into trouble...
00582                 break;
00583 
00584             //And find the next /../
00585             iFound=Path.Sub(sSlashDotDotSlash);
00586         }   
00587     }
00588     else
00589     {
00590         //No, this Web Address doesn't have a path.
00591         //So it inherits the path of the base URL.
00592         Path=Base.Path;
00593 
00594         //If this Web Address has some parameters, we need do nothin more to it
00595         if (!Parameters.IsEmpty())
00596             goto ReturnNow;
00597 
00598         //Otherwise this Web Address inherits the parameters of the base URL
00599         Parameters=Base.Parameters;
00600 
00601         //If this Web Address has a query, we need do nothin more to it
00602         if (!Query.IsEmpty())
00603             goto ReturnNow;
00604 
00605         //Otherwise this Web Address inherits the parameters of the base URL
00606         Query=Base.Query;
00607 
00608         //And that's it. (Fragments are never inherited).
00609         //So we can return.
00610         goto ReturnNow;
00611 
00612     }//End if (!Path.IsEmpty()) else...
00613 
00614 ReturnNow:
00615     //Set the "Absolute" flag to whatever it's meant to be, and return
00616     SetFlags();
00617     return;
00618 }
00619 
00620 /**********************************************************************************************
00621 
00622 >   String_256 WebAddress::GetWebAddress()
00623 
00624     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00625     Created:    17/9/96
00626     Inputs:     -
00627     Returns:    The full URL string
00628     Purpose:    Returns the URL string
00629 
00630 **********************************************************************************************/
00631 
00632 String_256 WebAddress::GetWebAddress()
00633 {
00634     String_256 strToReturn=Scheme;
00635 
00636     strToReturn+=NetLoc;
00637     strToReturn+=Path;
00638     strToReturn+=Parameters;
00639     strToReturn+=Query;
00640     strToReturn+=Fragment;
00641 
00642     return strToReturn;
00643 
00644 
00645 }
00646 
00647 
00648 /**********************************************************************************************
00649 
00650 >   BOOL WebAddress::IsHTTP()
00651 
00652     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00653     Created:    17/9/96
00654     Inputs:     -
00655     Returns:    TRUE if this Web Address starts with HTTP
00656     Purpose:    Finds whether this Web Address starts with "HTTP:"
00657 
00658 **********************************************************************************************/
00659 
00660 BOOL WebAddress::IsHTTP() const
00661 {
00662     return (Scheme.SubWithoutCase(String_256(_R(IDS_URL_HTTPCOLON)))==0);   
00663 }
00664 
00665 /**********************************************************************************************
00666 
00667 >   BOOL WebAddress::IsValidHTTP()
00668 
00669     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00670     Created:    27/6/97
00671     Inputs:     -
00672     Returns:    TRUE if this Web Address starts with HTTP and has a net location
00673     Purpose:    Finds whether this Web Address is a valid HTTP address.
00674 
00675                 We say it's a valid HTTP address if:
00676                 a. It starts with HTTP
00677                 b. It has a net location
00678 
00679                 Note that a valid http address may be valid but refer to a non-existent
00680                 network location - for example:
00681 
00682                 http://nonsensenonsense
00683 
00684                 is a valid HTTP URL that refers to a server called "nonsensenonsense", which
00685                 does not exist.
00686 
00687                 
00688 
00689 **********************************************************************************************/
00690 
00691 BOOL WebAddress::IsValidHTTP() const
00692 {
00693     return (IsHTTP() && !NetLocIsEmpty());  
00694 }
00695 
00696 
00697 /**********************************************************************************************
00698 
00699 >   static BOOL WebAddress::IsHTTP(const String_256& strTest)
00700 
00701     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00702     Created:    17/9/96
00703     Inputs:     -
00704     Returns:    TRUE if strTest starts with HTTP
00705     Purpose:    Finds whether strTest starts with "HTTP:"
00706 
00707 **********************************************************************************************/
00708 
00709 BOOL WebAddress::IsHTTP(const String_256& strTest)
00710 {
00711     WebAddress urlTest(strTest);
00712     return (urlTest.IsHTTP());  
00713 }
00714 
00715 
00716 /********************************************************************************************
00717 
00718     BOOL WebAddress::IsLocalFile()  
00719 
00720     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00721     Created:    10/6/97
00722     Inputs:     -
00723     Outputs:    -
00724 
00725     Returns:    TRUE if we consider pstrCorrect to be a local filename
00726                 FALSE otherwise
00727     
00728     Purpose:    Works out if we consider this Web Address to be a local filename.
00729 
00730                 It's a local filename if its scheme is "file:"
00731 
00732     Errors:     -
00733 
00734     SeeAlso:    WebAddress::GetPathName()
00735 
00736 ********************************************************************************************/
00737 
00738 BOOL WebAddress::IsLocalFile() const
00739 {   
00740     return( Scheme == wxT("file:") );
00741 }
00742 
00743 /********************************************************************************************
00744 
00745     PathName WebAddress::GetPathName()  
00746 
00747     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00748     Created:    10/6/97
00749     Inputs:     -
00750     Outputs:    -
00751 
00752     Returns:    The PathName that is equivalent to this URL.
00753     
00754     Purpose:    This is used to convert a local file URL (that is, a URL
00755                 whose scheme is "file:") to a pathname.
00756 
00757                 Before calling this function, call "IsLocalFile()" to
00758                 make sure the scheme is "file:".
00759 
00760                 For example, this function converts:
00761 
00762                 file://d|/dir1/file.htm to d:\dir1\file.htm
00763 
00764                 file:////Netloc/dir1/file.htm to \\Netloc\dir1\file.htm
00765 
00766                 It also converts the following URLs correctly. Note that
00767                 these URLs are illegal - but they appear in the IE3 
00768                 URL bar!
00769 
00770                 file://d:\dir1\file.htm to d:\dir1\file.htm
00771                 file://\\netloc\dir1\file.htm to \\netloc\dir1\file.htm
00772 
00773                 It does this as follows:
00774 
00775                 1. First, the "file:" part is removed
00776 
00777                 2. Then, if the net location starts with "//", that "//"
00778                    is removed.
00779 
00780                 3. All forward slashes are converted to backslashes
00781 
00782                 4. All "|" characters are converted to colons
00783 
00784                 Of course there's no guarantee that what's left is
00785                 a valid path name.              
00786 
00787     Errors:     -
00788 
00789     SeeAlso:    WebAddress::IsLocalFile()
00790 
00791 ********************************************************************************************/
00792 
00793 PathName WebAddress::GetPathName() const
00794 {   
00795     //We needn't actually do anything to remove the Scheme - we just don't
00796     //use it
00797 
00798     //First concatenate the net location and the path
00799     String_256 strToReturn=NetLoc;
00800     strToReturn+=Path;
00801     
00802     //So, does that string start with "//"?
00803     if (strToReturn.Sub(String_256("//"))==0)
00804     {
00805         //Yes. So remove it
00806         strToReturn.Split(NULL, &strToReturn, 1, TRUE);
00807     }
00808 
00809     //Convert all forward slashes to backslashes
00810     strToReturn.SwapChar('/', '\\');
00811 
00812     //Convert all | characters to colons
00813     strToReturn.SwapChar('|', ':');
00814 
00815     //Put our string into a PathName object
00816     PathName pthToReturn(strToReturn);
00817 
00818     //And return it
00819     return pthToReturn;
00820 
00821 }
00822 
00823 
00824 /********************************************************************************************
00825 
00826     WebAddress correction functions
00827 
00828     These functions correct the URL. For example, www.xara.com might be corrected
00829     to http://www.xara.com/
00830 
00831 ********************************************************************************************/
00832 
00833 /********************************************************************************************
00834 
00835     void WebAddress::Correct(String_256* pstrCorrect, WebCorrectFlags wcfToUse)  
00836 
00837     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00838     Created:    28/5/97
00839     Inputs:     pstrCorrect - the string to correct
00840                 wcfToUse    - a set of flags which detail how to correct
00841                               the string
00842     Outputs:    pstrCorrect - the corrected string
00843 
00844     Returns:    -
00845     
00846     Purpose:    Corrects the URL string that the user has entered, according to the
00847                 correction flags.
00848 
00849     Errors:     -
00850 
00851   SeeAlso:  WebAddress::ApplyWebAddressToSelection; WebCorrectFlags
00852 
00853 ********************************************************************************************/
00854 
00855 void WebAddress::Correct(String_256* pstrCorrect, WebCorrectFlags wcfToUse)  
00856 {   
00857     //If we should be correcting backslashes to forward slashes, do so now
00858     if (wcfToUse.CorrectBackslashes())
00859         CorrectBackslashes(pstrCorrect);
00860 
00861     //If we should be correcting local filenames
00862     if (wcfToUse.CorrectLocalFilenames() && ShouldCorrectLocalFilenames(pstrCorrect))
00863     {
00864         //Then correct it to a URL pointing to a local filename
00865         CorrectLocalFilenames(pstrCorrect);
00866     }
00867 
00868     //Now, if we should be correcting Netscape local URLs to IE3 ones
00869     if (wcfToUse.CorrectNetscapeFilenames() && ShouldCorrectNetscapeFilenames(pstrCorrect))
00870     {
00871         //Then correct it
00872         CorrectNetscapeFilenames(pstrCorrect);
00873     }
00874     //Otherwise if we should be correcting ftp addresses
00875     else if (wcfToUse.CorrectFTP() && ShouldCorrectFTP(pstrCorrect))
00876     {
00877         //Then add "ftp:" to the front
00878         CorrectFTP(pstrCorrect);
00879     }
00880     //Otherwise if we should be adding http:// to the front
00881     else if (wcfToUse.CorrectHTTP() && ShouldCorrectHTTP(pstrCorrect))
00882     {
00883         //Then add "http://" to the front
00884         CorrectHTTP(pstrCorrect);
00885             
00886     }
00887     //Otherwise if the string contains an @
00888     else if (ShouldCorrectMailto(pstrCorrect))
00889     {
00890         //Then add "mailto:" to the front
00891         CorrectMailto(pstrCorrect);
00892     }
00893 
00894     //If we should be ensuring that http addresses have a net location
00895     if (wcfToUse.CorrectNoNetLoc() && ShouldCorrectNoNetLoc(pstrCorrect))
00896     {
00897         //Then add a slash to the end
00898         CorrectNoNetLoc(pstrCorrect);
00899     }
00900 
00901 
00902     //And finally, if we should be adding a slash to the end
00903     if (wcfToUse.CorrectNoSlash() && ShouldCorrectNoSlash(pstrCorrect))
00904     {
00905         //Then add a slash to the end
00906         CorrectNoSlash(pstrCorrect);
00907     }
00908 
00909 }
00910 
00911 /********************************************************************************************
00912 
00913     void WebAddress::CorrectBackslashes(String_256* pstrCorrect)  
00914 
00915     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00916     Created:    28/5/97
00917     Inputs:     pstrCorrect - the string to correct
00918     Outputs:    pstrCorrect - the corrected string
00919 
00920     Returns:    -
00921     
00922     Purpose:    Corrects any backslashes in the entered string to slashes
00923 
00924     Errors:     -
00925 
00926     SeeAlso:    WebAddress::Correct()
00927 
00928 ********************************************************************************************/
00929 
00930 void WebAddress::CorrectBackslashes(String_256* pstrCorrect)  
00931 {   
00932     //Check our parameter
00933     if (pstrCorrect==NULL)
00934     {
00935         ERROR2RAW("WebAddress::CorrectBackslashes - NULL parameter");
00936         return;
00937     }
00938 
00939     //And correct all backslashes to forward slashes
00940     pstrCorrect->SwapChar('\\', '/');
00941 
00942 }
00943 
00944 /********************************************************************************************
00945 
00946     BOOL WebAddress::ShouldCorrectLocalFilenames(String_256* pstrCorrect)  
00947 
00948     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00949     Created:    28/5/97
00950     Inputs:     pstrCorrect - the string to test
00951     Outputs:    -
00952 
00953     Returns:    TRUE if we consider pstrCorrect to be a local filename
00954                 FALSE otherwise
00955     
00956     Purpose:    Works out if we consider this string to be a local filename.
00957 
00958                 We consider this to be a local filename if
00959                 a. It begins with a letter followed by a colon
00960                 b. It begins with \\, in which case it is a UNC pathname
00961 
00962     Errors:     -
00963 
00964     SeeAlso:    WebAddress::Correct()
00965 
00966 ********************************************************************************************/
00967 
00968 BOOL WebAddress::ShouldCorrectLocalFilenames(String_256* pstrCorrect)  
00969 {   
00970     //Check our parameter
00971     ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectBackslash - NULL parameter");
00972     
00973     //If the length of the string is less than two characters, return FALSE
00974     if (pstrCorrect->Length()<2)
00975         return FALSE;
00976 
00977     //Now, if the first character is a letter and the second character is a
00978     //colon, return TRUE
00979     if (StringBase::IsAlpha((*pstrCorrect)[0]) && (*pstrCorrect)[1]==':')
00980     {
00981         return TRUE;
00982     }
00983                                                                              
00984     //Otherwise, if the first two characters are forward slashes, return TRUE
00985     if ((*pstrCorrect)[0]=='/' && (*pstrCorrect)[1]=='/')
00986     {
00987         return TRUE;
00988     }
00989     
00990     //Otherwise return FALSE
00991     return FALSE;
00992 
00993 }
00994 
00995 /********************************************************************************************
00996 
00997     void WebAddress::CorrectLocalFilenames(String_256* pstrCorrect)  
00998 
00999     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01000     Created:    28/5/97
01001     Inputs:     pstrCorrect - the string to correct
01002     Outputs:    pstrCorrect - the corrected string
01003 
01004     Returns:    -
01005     
01006     Purpose:    Assumes pstrCorrect is a local filename, then converts
01007                 it to a URL referring to a local filename.
01008 
01009                 It does this by calling the function PathName::GetWebAddress()
01010 
01011     Errors:     -
01012 
01013     SeeAlso:    WebAddress::Correct(), PathName::GetWebAddress()
01014 
01015 ********************************************************************************************/
01016 
01017 void WebAddress::CorrectLocalFilenames(String_256* pstrCorrect)  
01018 {   
01019     //Check our parameter
01020     if(pstrCorrect==NULL)
01021     {
01022         ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
01023         return;
01024     }
01025 
01026     
01027     //Now, create a pathname out of our string
01028     PathName pthTemp=*pstrCorrect;
01029 
01030     //And call the GetWebAddress function
01031     *pstrCorrect=pthTemp.GetWebAddress();
01032 
01033 }
01034 
01035 /********************************************************************************************
01036 
01037     BOOL WebAddress::ShouldCorrectNetscapeFilenames(String_256* pstrCorrect)  
01038 
01039     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01040     Created:    25/6/97
01041     Inputs:     pstrCorrect - the string to test
01042     Outputs:    -
01043 
01044     Returns:    TRUE if we consider pstrCorrect to be a Netscape local filename.
01045                 FALSE otherwise
01046     
01047     Purpose:    Works out if we consider this string to be a Netscape local filename.
01048 
01049                 We consider this to be a Netscape local filename if it begins
01050                 with "file:///", but does not begin with "file:////".
01051 
01052                 The problem here is that Netscape refers to local filenames as follows:
01053 
01054                 file:///d|/dir1/myname.htm
01055 
01056                 But IE3 refers to local filenames as:
01057 
01058                 file://d|/dir1/myname.htm
01059 
01060                 Note the difference in the number of slashes. We correct it to the IE3 version.
01061                 
01062 
01063     Errors:     -
01064 
01065     SeeAlso:    WebAddress::Correct()
01066 
01067 ********************************************************************************************/
01068 
01069 BOOL WebAddress::ShouldCorrectNetscapeFilenames(String_256* pstrCorrect)  
01070 {   
01071     //Check our parameter
01072     ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectNetscapeFilenames - NULL parameter");
01073 
01074     //Set up some strings to search for
01075     String_256 strThreeSlashes("file:///");
01076     String_256 strFourSlashes("file:////");
01077 
01078     //Now, if the string begins with "file:///"...
01079     if (pstrCorrect->SubWithoutCase(strThreeSlashes)==0)
01080     {
01081         //But the string doesn't begin with "file:////"
01082         if (pstrCorrect->SubWithoutCase(strFourSlashes)!=0)
01083             //Then we shoul correct it
01084             return TRUE;
01085     }
01086         
01087     //Otherwise return FALSE
01088     return FALSE;
01089 
01090 }
01091 
01092 /********************************************************************************************
01093 
01094     void WebAddress::CorrectNetscapeFilenames(String_256* pstrCorrect)  
01095 
01096     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01097     Created:    28/5/97
01098     Inputs:     pstrCorrect - the string to correct
01099     Outputs:    pstrCorrect - the corrected string
01100 
01101     Returns:    -
01102     
01103       Purpose:  Converts a Netscape local filename (file:///xxxxxxx) to an IE3 local filename
01104                 (file://xxxxxxx) by simply removing the third slash.
01105 
01106     Errors:     -
01107 
01108     SeeAlso:    WebAddress::Correct(), PathName::GetWebAddress()
01109 
01110 ********************************************************************************************/
01111 
01112 void WebAddress::CorrectNetscapeFilenames(String_256* pstrCorrect)  
01113 {   
01114     //Check our parameter
01115     if(pstrCorrect==NULL)
01116     {
01117         ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
01118         return;
01119     }
01120                                                                         
01121     //Simply delete the fifth character, removing one of the slashes
01122     pstrCorrect->Remove(6, 1);
01123 
01124 }
01125 
01126 /********************************************************************************************
01127 
01128     BOOL WebAddress::ShouldCorrectFTP(String_256* pstrCorrect)  
01129 
01130     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01131     Created:    28/5/97
01132     Inputs:     pstrCorrect - the string to test
01133     Outputs:    -
01134 
01135     Returns:    TRUE if we consider pstrCorrect to be an ftp address
01136                 FALSE otherwise
01137     
01138     Purpose:    Works out if we consider this string to be a ftp address with
01139                 the "ftp:" missing.
01140 
01141                 We do so if the string starts "ftp.".
01142 
01143     Errors:     -
01144 
01145     SeeAlso:    WebAddress::Correct()
01146 
01147 ********************************************************************************************/
01148 
01149 BOOL WebAddress::ShouldCorrectFTP(String_256* pstrCorrect)  
01150 {   
01151     //Check our parameter
01152     ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectBackslash - NULL parameter");
01153     
01154     //Are the first four characters "ftp." ?
01155     if (pstrCorrect->SubWithoutCase(String_256("ftp."))==0)
01156         return TRUE;
01157     
01158     //Otherwise return FALSE
01159     return FALSE;
01160 
01161 }
01162 
01163 /********************************************************************************************
01164 
01165     void WebAddress::CorrectFTP(String_256* pstrCorrect)  
01166 
01167     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01168     Created:    28/5/97
01169     Inputs:     pstrCorrect - the string to correct
01170     Outputs:    pstrCorrect - the corrected string
01171 
01172     Returns:    -
01173     
01174       Purpose:  Puts "ftp:" on the start of pstrCorrect.
01175 
01176     Errors:     -
01177 
01178     SeeAlso:    WebAddress::Correct()
01179 
01180 ********************************************************************************************/
01181 
01182 void WebAddress::CorrectFTP(String_256* pstrCorrect)  
01183 {   
01184     //Check our parameter
01185     if(pstrCorrect==NULL)
01186     {
01187         ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
01188         return;
01189     }
01190     
01191     //If our string is over two hundred and fifty characters long, return
01192     if (pstrCorrect->Length()>250)
01193         return;
01194 
01195     //Otherwise, create a new string containing "ftp://"
01196     String_256 strToReturn="ftp://";
01197 
01198     //Add our other string onto the end of it
01199     strToReturn+=*pstrCorrect;
01200 
01201     //And copy our new string into our old string
01202     *pstrCorrect=strToReturn;
01203 }
01204 
01205 /********************************************************************************************
01206 
01207     BOOL WebAddress::ShouldCorrectHTTP(String_256* pstrCorrect)  
01208 
01209     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01210     Created:    28/5/97
01211     Inputs:     pstrCorrect - the string to test
01212     Outputs:    -
01213 
01214     Returns:    TRUE if we consider pstrCorrect to be an http address
01215                 FALSE otherwise
01216     
01217     Purpose:    Works out if we consider this string to be a http address with
01218                 the "http:" missing.
01219 
01220                 We do so if the string starts with a string of the following
01221                 characters:
01222                 
01223                   ;?:&=%$-_.+!*'(),abcdefghijklmnopqrstuvwxyz
01224                   ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
01225 
01226                 ...which contains at least two full stops. (This string
01227                 of characters is taken from http://ds.internic.net/rfc/rfc1808.txt,
01228                 page 4, but altered slightly).
01229                 
01230                 The first character should not be a full stop and there
01231                 should not be two full stops together.
01232 
01233                 For example:        
01234 
01235                 abc-def12.gh4i3.jkl.mno
01236 
01237     Errors:     -
01238 
01239     SeeAlso:    WebAddress::Correct()
01240 
01241 ********************************************************************************************/
01242 
01243 BOOL WebAddress::ShouldCorrectHTTP(String_256* pstrCorrect)  
01244 {   
01245     //Check our parameter
01246     ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectBackslash - NULL parameter");
01247 
01248     //Get the length of the string
01249     INT32 iLength=pstrCorrect->Length();
01250 
01251     //If the string is empty, return FALSE
01252     if (iLength<=0)
01253         return FALSE;
01254 
01255     //Now, here is the set of characters to test for
01256     TCHAR              *strAllowed = _T(";?&=%abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$-_.+!*'(),");
01257     
01258     //If the first character is a full stop, return FALSE
01259     if ((*pstrCorrect)[0]=='.')
01260         return FALSE;
01261 
01262     //And this variable will keep a count of the number of full stops
01263     INT32 iFullStops=0;
01264 
01265     //This variable will tell us if the last character we looked at
01266     //was a full stop
01267     BOOL fLastCharWasFullStop=FALSE;
01268 
01269     //Now, starting at the first character in the string, scan through
01270     //each character in turn until we get to something that is not
01271     //in our set of allowed characters
01272     for (INT32 i=0; i<iLength && (camStrchr(strAllowed, (*pstrCorrect)[i]))!=NULL; i++)
01273          {
01274              //If the letter we are looking at is a full stop,
01275               if ((*pstrCorrect)[i]=='.')
01276               {
01277                   //Then, was the last character we looked at a full stop?
01278                   if (fLastCharWasFullStop)
01279                   {
01280                       //Yes. So we've found two full stops together. Return FALSE
01281                       return FALSE;
01282                   }
01283                   else
01284                   {
01285                       //No. So add one to our count of full stops and remember
01286                       //that this character was a full stop
01287                        iFullStops++;
01288                        fLastCharWasFullStop=TRUE;
01289                   }
01290               }
01291               else
01292               {
01293                   //No, this character is not a full stop
01294                   fLastCharWasFullStop=FALSE;
01295               }
01296          }
01297 
01298     //And return true if we found more than one full stop   
01299     return (iFullStops>=2);
01300 
01301 }
01302 
01303 /********************************************************************************************
01304 
01305     void WebAddress::CorrectHTTP(String_256* pstrCorrect)  
01306 
01307     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01308     Created:    28/5/97
01309     Inputs:     pstrCorrect - the string to correct
01310     Outputs:    pstrCorrect - the corrected string
01311 
01312     Returns:    -
01313     
01314       Purpose:  Puts "http:" on the start of pstrCorrect.
01315 
01316     Errors:     -
01317 
01318     SeeAlso:    WebAddress::Correct()
01319 
01320 ********************************************************************************************/
01321 
01322 void WebAddress::CorrectHTTP(String_256* pstrCorrect)  
01323 {   
01324     //Check our parameter
01325     if(pstrCorrect==NULL)
01326     {
01327         ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
01328         return;
01329     }
01330     
01331     //If our string is over two hundred and fifty characters long, return
01332     if (pstrCorrect->Length()>250)
01333         return;
01334 
01335     //Otherwise, create a new string containing "http:"
01336     String_256 strToReturn="http://";
01337 
01338     //Add our other string onto the end of it
01339     strToReturn+=*pstrCorrect;
01340 
01341     //And copy our new string into our old string
01342     *pstrCorrect=strToReturn;
01343 }
01344 
01345 /********************************************************************************************
01346 
01347     BOOL WebAddress::ShouldCorrectNoSlash(String_256* pstrCorrect)  
01348 
01349     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01350     Created:    28/5/97
01351     Inputs:     pstrCorrect - the string to test
01352     Outputs:    -
01353 
01354     Returns:    TRUE if we consider that pstrCorrect is a URL to which the
01355                 user has forgotten to add a trailing slash
01356                 FALSE otherwise
01357     
01358     Purpose:    Works out if we consider this string to be a URL with a trailing
01359                 slash missing.
01360 
01361                 We do this by creating a Web Address object to parse the string.
01362                 (Note that if this function is called, then the URL will already
01363                 have had an "http://" added to the front if necessary).
01364 
01365                 Then we consider that the URL should have a slash added if
01366                 a. The string consists of a net location but no path 
01367                 (e.g. "http://www.xara.com", which should become 
01368                 "http://www.xara.com/")
01369 
01370                 b. The path portion of the URL does not end in a slash, and
01371                    the final segment of the path does not have a full stop
01372                    character in it.
01373 
01374                     That is, "http://www.bbc.co.uk/radio1" should have a slash
01375                     added on the end, but "http://www.bbc.co.uk/index.htm" should
01376                     not.
01377 
01378 
01379     Errors:     -
01380 
01381     SeeAlso:    WebAddress::Correct()
01382 
01383 ********************************************************************************************/
01384 
01385 BOOL WebAddress::ShouldCorrectNoSlash(String_256* pstrCorrect)  
01386 {   
01387     //Check our parameter
01388     ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectNoSlash - NULL parameter");
01389     
01390     //First create a Web Address from our string
01391     WebAddress urlTest(*pstrCorrect);
01392 
01393     //Now, does the Web Address start with HTTP:, and does it have a net location
01394     //specified?
01395     if (urlTest.IsHTTP() && !urlTest.NetLocIsEmpty())
01396     {
01397         //Yes.
01398 
01399         //So, does the Web Address have an empty path?
01400         if (urlTest.PathIsEmpty())
01401         {
01402             //Yes. So we should add a slash to it.
01403             return TRUE;
01404         }
01405         else
01406         {
01407             //No, there is something in the path.
01408 
01409             //So, does the path end in something other than a slash?
01410             INT32 iLength=urlTest.Path.Length();
01411 
01412             if (urlTest.Path[iLength-1]!='/')
01413             {
01414                 //Yes. So we should add a slash only if 
01415                 //the last segment of the path does not contain a full stop.
01416 
01417                 //First try and find a slash in the path string, starting
01418                 //from the end
01419                 INT32 iSlashFound=urlTest.Path.ReverseFind('/');
01420 
01421                 //Now try and find a full stop in the path string, starting 
01422                 //from the end
01423                 INT32 iFullStopFound=urlTest.Path.ReverseFind('.');
01424 
01425                 //Now...
01426 
01427                 //If we didn't find a full stop, we should add a slash
01428                 if (iFullStopFound==-1)
01429                     return TRUE;
01430 
01431                 //Otherwise, we should only add a slash if the slash
01432                 //was found after the full stop
01433                 if (iSlashFound>iFullStopFound)
01434                     return TRUE;
01435 
01436                 //Otherwise, we don't add a slash
01437             }
01438         }
01439     }
01440 
01441     //So, none of our conditions were met.
01442     //So we don't add a slash
01443     return FALSE;
01444 }
01445 
01446 /********************************************************************************************
01447 
01448     void WebAddress::CorrectNoSlash(String_256* pstrCorrect)  
01449 
01450     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01451     Created:    28/5/97
01452     Inputs:     pstrCorrect - the string to correct
01453     Outputs:    pstrCorrect - the corrected string
01454 
01455     Returns:    -
01456     
01457     Purpose:    Adds a slash to the end of the string
01458 
01459 
01460     Errors:     -
01461 
01462     SeeAlso:    WebAddress::Correct(); WebAddress::ShouldCorrectNoSlash()
01463 
01464 ********************************************************************************************/
01465 
01466 void WebAddress::CorrectNoSlash(String_256* pstrCorrect)  
01467 {   
01468     //Check our parameter
01469     if(pstrCorrect==NULL)
01470     {
01471         ERROR2RAW("WebAddress::CorrectNoSlash - NULL parameter");
01472         return;
01473     }
01474     
01475     //And if the string is long enough
01476     if (pstrCorrect->Length()<255)
01477     {
01478         //Add a slash to the end
01479         *pstrCorrect+='/';
01480     }
01481 }
01482 
01483 
01484 
01485 
01486 
01487 /********************************************************************************************
01488 
01489     BOOL WebAddress::ShouldCorrectMailto(String_256* pstrCorrect)  
01490 
01491     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01492     Created:    28/5/97
01493     Inputs:     pstrCorrect - the string to test
01494     Outputs:    -
01495 
01496     Returns:    TRUE if we consider pstrCorrect to be a mail address
01497                 FALSE otherwise
01498     
01499     Purpose:    Works out if we consider this string to be a mail address with
01500                 the "mailto:" missing.
01501 
01502                 We do so if it contains an @ character and does not
01503                 contain a colon
01504 
01505     Errors:     -
01506 
01507     SeeAlso:    WebAddress::Correct()
01508 
01509 ********************************************************************************************/
01510 
01511 BOOL WebAddress::ShouldCorrectMailto(String_256* pstrCorrect)  
01512 {   
01513     //Check our parameter
01514     ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectBackslash - NULL parameter");
01515     
01516     //Find the first @ symbol
01517     INT32 iLocationOfAtSymbol=pstrCorrect->FindNextChar('@');
01518 
01519     //If we found one
01520     if (iLocationOfAtSymbol>0)
01521     {
01522         //Then check for a colon
01523         INT32 iLocationOfColon=pstrCorrect->FindNextChar(':');
01524 
01525         //If we didn't find one, return TRUE
01526         if (iLocationOfColon<0)
01527             return TRUE;
01528     }
01529     
01530     return FALSE;
01531 
01532 }
01533 
01534 /********************************************************************************************
01535 
01536     void WebAddress::CorrectMailto(String_256* pstrCorrect)  
01537 
01538     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01539     Created:    28/5/97
01540     Inputs:     pstrCorrect - the string to correct
01541     Outputs:    pstrCorrect - the corrected string
01542 
01543     Returns:    -
01544     
01545       Purpose:  Puts "mailto:" on the start of pstrCorrect.
01546 
01547     Errors:     -
01548 
01549     SeeAlso:    WebAddress::Correct()
01550 
01551 ********************************************************************************************/
01552 
01553 void WebAddress::CorrectMailto(String_256* pstrCorrect)  
01554 {   
01555     //Check our parameter
01556     if(pstrCorrect==NULL)
01557     {
01558         ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
01559         return;
01560     }
01561     
01562     //If our string is over two hundred and fifty characters long, return
01563     if (pstrCorrect->Length()>250)
01564         return;
01565 
01566     //Otherwise, create a new string containing "mailto:"
01567     String_256 strToReturn="mailto:";
01568 
01569     //Add our other string onto the end of it
01570     strToReturn+=*pstrCorrect;
01571 
01572     //And copy our new string into our old string
01573     *pstrCorrect=strToReturn;
01574 }
01575 
01576 /********************************************************************************************
01577 
01578     BOOL WebAddress::ShouldCorrectNoNetLoc(String_256* pstrCorrect)  
01579 
01580     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01581     Created:    27/6/97
01582     Inputs:     pstrCorrect - the string to test
01583     Outputs:    -
01584 
01585     Returns:    TRUE if pstrCorrect starts with "http" but does not
01586                 have "//" afterwards to signify a net location
01587                 FALSE otherwise
01588     
01589     Purpose:    Works out if we consider this string to be an HTTP address
01590                 with the "//" to signify a network location missing. For example:
01591 
01592                 http:www.xara.com
01593 
01594     Errors:     -
01595 
01596     SeeAlso:    WebAddress::Correct()
01597 
01598 ********************************************************************************************/
01599 
01600     BOOL WebAddress::ShouldCorrectNoNetLoc(String_256* pstrCorrect)  
01601 {   
01602     //Check our parameter
01603     ERROR2IF(pstrCorrect==NULL, FALSE, "WebAddress::CorrectBackslash - NULL parameter");
01604     
01605     //Return TRUE if the string starts with "http:" but doesn't start with "http://"
01606     String_256 strHTTP("http:");
01607     String_256 strHTTPSlashSlash("http://");
01608 
01609     return (pstrCorrect->SubWithoutCase(strHTTP)==0 && pstrCorrect->SubWithoutCase(strHTTPSlashSlash)!=0);
01610 
01611 }
01612 
01613 /********************************************************************************************
01614 
01615     void WebAddress::CorrectNoNetLoc(String_256* pstrCorrect)  
01616 
01617     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01618     Created:    28/5/97
01619     Inputs:     pstrCorrect - the string to correct
01620     Outputs:    pstrCorrect - the corrected string
01621 
01622     Returns:    -
01623     
01624       Purpose:  Ensures that pstrCorrect starts with "http://"
01625 
01626     Errors:     -
01627 
01628     SeeAlso:    WebAddress::Correct()
01629 
01630 ********************************************************************************************/
01631 
01632 void WebAddress::CorrectNoNetLoc(String_256* pstrCorrect)  
01633 {   
01634     //Check our parameter
01635     if(pstrCorrect==NULL)
01636     {
01637         ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
01638         return;
01639     }
01640     
01641     //We already know that our string does not start with "http://"
01642     //But does it start with "http:/"?
01643     if (pstrCorrect->SubWithoutCase(String_256("http:/"))==0)
01644     {
01645         //Yes it does. So insert an extra slash
01646         pstrCorrect->Insert( String_256("/"), 5 );
01647     }
01648     else
01649     {
01650         //No it doesn't. So insert an extra two slashes after the HTTP
01651         pstrCorrect->Insert( String_256("//"), 5 );
01652     }
01653 }
01654 
01655 
01656 
01657 
01658 

Generated on Sat Nov 10 03:47:21 2007 for Camelot by  doxygen 1.4.4