stemplate.cpp

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

Generated on Sat Nov 10 03:48:57 2007 for Camelot by  doxygen 1.4.4