1 // $Id: stemplate.cpp 1282 2006-06-09 09:46:49Z alex $
2 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
3 ================================XARAHEADERSTART===========================
5 Xara LX, a vector drawing and manipulation program.
6 Copyright (C) 1993-2006 Xara Group Ltd.
7 Copyright on certain contributions may be held in joint with their
8 respective authors. See AUTHORS file for details.
10 LICENSE TO USE AND MODIFY SOFTWARE
11 ----------------------------------
13 This file is part of Xara LX.
15 Xara LX is free software; you can redistribute it and/or modify it
16 under the terms of the GNU General Public License version 2 as published
17 by the Free Software Foundation.
19 Xara LX and its component source files are distributed in the hope
20 that it will be useful, but WITHOUT ANY WARRANTY; without even the
21 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22 See the GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License along
25 with Xara LX (see the file GPL in the root directory of the
26 distribution); if not, write to the Free Software Foundation, Inc., 51
27 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 Conditional upon your continuing compliance with the GNU General Public
34 License described above, Xara Group Ltd grants to you certain additional
37 The additional rights are to use, modify, and distribute the software
38 together with the wxWidgets library, the wxXtra library, and the "CDraw"
39 library and any other such library that any version of Xara LX relased
40 by Xara Group Ltd requires in order to compile and execute, including
41 the static linking of that library to XaraLX. In the case of the
42 "CDraw" library, you may satisfy obligation under the GNU General Public
43 License to provide source code by providing a binary copy of the library
44 concerned and a copy of the license accompanying it.
46 Nothing in this section restricts any of the rights you have under
47 the GNU General Public License.
53 This license applies to this program (XaraLX) and its constituent source
54 files only, and does not necessarily apply to other Xara products which may
55 in part share the same code base, and are subject to their own licensing
58 This license does not apply to files in the wxXtra directory, which
59 are built into a separate library, and are subject to the wxWindows
60 license contained within that directory in the file "WXXTRA-LICENSE".
62 This license does not apply to the binary libraries (if any) within
63 the "libs" directory, which are subject to a separate license contained
64 within that directory in the file "LIBS-LICENSE".
67 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
68 ----------------------------------------------
70 Subject to the terms of the GNU Public License (see above), you are
71 free to do whatever you like with your modifications. However, you may
72 (at your option) wish contribute them to Xara's source tree. You can
73 find details of how to do this at:
74 http://www.xaraxtreme.org/developers/
76 Prior to contributing your modifications, you will need to complete our
77 contributor agreement. This can be found at:
78 http://www.xaraxtreme.org/developers/contribute/
80 Please note that Xara will not accept modifications which modify any of
81 the text between the start and end of this header (marked
82 XARAHEADERSTART and XARAHEADEREND).
88 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
89 designs are registered or unregistered trademarks, design-marks, and/or
90 service marks of Xara Group Ltd. All rights in these marks are reserved.
93 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
96 =================================XARAHEADEREND============================
100 #include "camtypes.h"
103 //#include "ccobject.h" - in camtypes.h [AUTOMATICALLY REMOVED]
104 //#include "pathname.h" - in camtypes.h [AUTOMATICALLY REMOVED]
106 //#include "resimmap.h"
109 DECLARE_SOURCE("$Revision: 1282 $");
111 CC_IMPLEMENT_DYNAMIC(WebAddress
, CCObject
)
113 /**********************************************************************************************
115 > WebAddress::WebAddress()
117 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
122 Purpose: Default WebAddress class constructor
125 **********************************************************************************************/
127 WebAddress::WebAddress()
132 /**********************************************************************************************
134 > WebAddress::WebAddress(const WebAddress& newPath)
136 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
141 Purpose: Copy Constructor for the WebAddress class
144 **********************************************************************************************/
146 WebAddress::WebAddress(const WebAddress
& InAddress
)
148 Absolute
= InAddress
.Absolute
;
150 Scheme
=InAddress
.Scheme
;
151 NetLoc
=InAddress
.NetLoc
;
153 Parameters
=InAddress
.Parameters
;
154 Query
=InAddress
.Query
;
155 Fragment
=InAddress
.Fragment
;
158 /**********************************************************************************************
160 > WebAddress& WebAddress::operator=(const WebAddress& InAddress)
162 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
167 Purpose: Assignment operator
170 **********************************************************************************************/
172 WebAddress
& WebAddress::operator=(const WebAddress
& InAddress
)
174 Absolute
= InAddress
.Absolute
;
176 Scheme
=InAddress
.Scheme
;
177 NetLoc
=InAddress
.NetLoc
;
179 Parameters
=InAddress
.Parameters
;
180 Query
=InAddress
.Query
;
181 Fragment
=InAddress
.Fragment
;
186 /**********************************************************************************************
188 > WebAddress::WebAddress(const String_256&, WebCorrectFlags wcfToUse=WebCorrectFlags())
190 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
192 Inputs: StringToParse String representing the path.
193 wcfToUse Flags indicating how the string should be
194 corrected before it is parsed. Some options
195 are: www.xara.com should be corrected to
196 http://www.xara.com/, d:\dir1\filename.gif
197 should be corrected to file://d|/dir1/filename.gif.
201 Purpose: Corrects the string, then parses the corrected string.
202 SeeAlso: WebCorrectFlags
204 **********************************************************************************************/
206 WebAddress::WebAddress(const String_256
& StringToParse
, WebCorrectFlags wcfToUse
)
208 //First make a copy of the string we've been given
209 String_256 strCopy
=StringToParse
;
211 //And correct the copy
212 Correct(&strCopy
, wcfToUse
);
214 //Then parse the corrected string
217 //And finally set the class's flags
221 /**********************************************************************************************
223 > INT32 WebAddress::operator==(WebAddress& Other)
225 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
231 Purpose: Equality operator
232 SeeAlso: WebCorrectFlags
234 **********************************************************************************************/
236 INT32
WebAddress::operator==(WebAddress
& Other
)
238 return (Scheme
==Other
.Scheme
&&
239 NetLoc
==Other
.NetLoc
&&
241 Parameters
==Other
.Parameters
&&
242 Query
==Other
.Query
&&
243 Fragment
==Other
.Fragment
);
248 /**********************************************************************************************
250 > WebAddress::Parse()
252 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
254 Inputs: String representing the full URL
257 Purpose: Takes the string and splits it into its component parts.
259 Notes: The parsing rules follow the guidelines given in
260 http://ds.internic.net/rfc/rfc1808.txt. So there!
261 (That means, don't change them unless you know what you're doing).
263 These rules can be pretty unforgiving...if you get the query, fragment
264 and parameters in the wrong order, the parsing rules don't accommodate
265 this. But I'm sticking with the rules because of funny things like...
266 a query could, theoretically, have a # in the middle of it.
268 Note that this parsing function should split InString into
269 several different strings and put those strings into
270 member variables, but it should not change the actual text
273 In other words, if you concatenate the following member
276 Scheme+NetLoc+Path+Parameters+Query+Fragment
278 You should *always* end up with the string InString you passed into
281 *Please* don't change the parsing rules unless you really know what
282 you're doing and have read the guideline document referred to above.
283 The parsing that is performed below may look easy, but it is
284 performed by qualified professionals and is extremely dangerous.
285 Do not imitate the parsing that you see below at home.
287 **********************************************************************************************/
289 BOOL
WebAddress::Parse(const String_256
& InString
)
291 //First set all the member strings to zero.
302 //If InString="", that's all we need to do...
303 if (InString
.IsEmpty())
306 //And set up a couple of strings we can play around with
307 String_256 StringToParse
=InString
;
309 //If the parse string is empty, we need do nothing, because all our fields are
310 //already blank. Return TRUE.
312 if (StringToParse
.IsEmpty()) return TRUE
;
314 //Now set up some strings. These are all hard coded cos it reduces code size
315 //This shouldn't matter for purposes of internationalisation, because URLs
316 //are an international system.
317 String_256 sNetloc
="//";
319 INT32 iLowerCaseA
=INT32 ('a');
320 INT32 iLowerCaseZ
=INT32 ('z');
321 INT32 iUpperCaseA
=INT32 ('A');
322 INT32 iUpperCaseZ
=INT32 ('Z');
324 char cBackslash
='\\';
328 char cQuestionmark
='?';
331 //First we want to find the Fragment section of the URL.
332 //This should start with a #
333 INT32 iFound
=StringToParse
.FindNextChar(cHash
);
335 //If we've found a #, copy the whole identifier into the "fragment" member variable
337 StringToParse
.Split(&StringToParse
, &Fragment
, iFound
, FALSE
);
339 //Now search the parse string for a scheme (the bit at the start,
340 //e.g. http:). To do this we search for a colon.
341 iFound
=StringToParse
.FindNextChar(cColon
);
343 //Have we found a colon?
348 //Yes. We now need to check that everything before that colon is a letter.
349 for (INT32 iStringPtr
=(iFound
-1); iStringPtr
>=0; iStringPtr
--)
351 if (!StringBase::IsAlpha(StringToParse
[iStringPtr
]))
358 //Was everything before the colon a letter?
360 //Yes, so split the string after that colon
361 StringToParse
.Split(&Scheme
, &StringToParse
, iFound
, TRUE
);
364 //Now look for a network location
365 iFound
=StringToParse
.Sub(sNetloc
);
367 //Have we found a //?
370 //Yes. So find the next / (or the end of the string)
372 //To do this, set up a string pointer that starts from two
373 //characters after iFound
374 INT32 iStringPtr
=iFound
+2;
376 //And move that string pointer forwards until
377 //either it points at a slash or it reaches the end of the
379 while (iStringPtr
<StringToParse
.Length() && StringToParse
[iStringPtr
]!=cSlash
)
384 StringToParse
.Split(&NetLoc
, &StringToParse
, iStringPtr
, FALSE
);
387 //Now look for query information.
388 iFound
=StringToParse
.FindNextChar(cQuestionmark
);
390 //Have we found a question mark?
392 StringToParse
.Split(&StringToParse
, &Query
, iFound
,FALSE
);
395 //Now look for parameter information.
396 iFound
=StringToParse
.FindNextChar(cSemicolon
);
398 //Have we found a semicolon?
400 StringToParse
.Split(&StringToParse
, &Parameters
, iFound
, FALSE
);
402 //And whatever is left is the path.
409 /**********************************************************************************************
411 > void WebAddress::SetFlags()
413 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
415 Purpose: Sets the Web Address flags - at the moment the only flag is Absolute - by
416 looking at the Web Address string member variables.
418 **********************************************************************************************/
420 BOOL
WebAddress::SetFlags()
422 Absolute
=!Scheme
.IsEmpty();
427 /**********************************************************************************************
429 > void WebAddress::Combine(WebAddress Base)
431 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
434 Purpose: Combines this Web Address with a base Web Address.
436 This is used when this Web Address is relative and the base
437 web address is the address of the current document. This function
438 allows this Web Address to inherit the appropriate components of the
439 base address so this Address becomes relative.
441 This is quite hard to explain, so here's an example: if this Web
442 address is "myfile.xar" and the base Web Address is
443 "http://www.xara.com/currentfile.xar" then this function makes
444 this Web Address into "http://www.xara.com/myfile.xar".
446 This function follows the guidelines given in some international
447 standard somewhere. (The one I was talking about above)
449 Because it follows these guidelines (almost) exactly, this function
450 contains one hell of a lot of loops within loops. Sorry! I've tried
451 to comment them helpfully.
453 Notes: The parsing rules follow the guidelines given in
454 http://ds,internic.net/rfc/rfc1808.txt.
456 *Please* don't change the parsing rules unless you really know what
457 you're doing and have read the guideline document referred to above.
458 The code below is written according to that document. Do not imitate
459 at home what you have seen on Gladiators, etc, etc.
461 **********************************************************************************************/
463 void WebAddress::Combine(WebAddress Base
)
465 //Strings are hard coded to reduce code size
466 String_256 sSlashDotSlash
="/./";
467 String_256 sSlashDotDotSlash
="/../";
471 //Now start the parsing.
473 //If the base Web Address is empty, this Web Address does not change
477 //If this Web Address is empty, then it inherits everything from the
481 Absolute
= Base
.Absolute
;
486 Parameters
=Base
.Parameters
;
488 Fragment
=Base
.Fragment
;
492 //If this Web Address is absolute, it does not change
496 //If none of the above apply, this Web Address inherits the scheme of
500 //If this Web Address has a net location, we need do nothing more to it.
501 if (!NetLoc
.IsEmpty())
504 //Otherwise, this Web Address inherits the Net Location of the base address.
507 //If the path of this Web Address starts with a slash, it is non-relative
508 //and we need only add it on to the Net Location
509 if ((*(Path
))==cSlash
) goto ReturnNow
;
512 //This is where all the loops within loops start. Hang on to your curly brackets.
514 //Does this Web Address have a path?
517 //Yes. Then the full path is given by:
518 //The Base URL path up to the rightmost slash + the URL of this Web Address
520 //This string will hold the base URL path up to the rightmost slash
521 String_256 sTempPath
="";
523 //First find the rightmost slash in Base.Path
524 INT32 iFound
=Base
.Path
.ReverseFind(cSlash
);
526 //Did we find a slash?
529 //Yes. So copy everything up to that slash into sTempPath
532 Base
.Path
.Split(&sTempPath
, NULL
, iFound
, TRUE
);
537 }//End IF there's a slash in Base.Path
540 //We now need to check the path for ../ and ./
541 //First let's search for /./
542 iFound
=Path
.Sub(sSlashDotSlash
);
544 //If we've found a /./
547 //Then remove the ./ part of it.
548 Path
.Remove(iFound
+1, 2);
550 //And look for the next /./ to remove
551 iFound
=Path
.Sub(sSlashDotSlash
);
554 //Now we want to remove all occurrences of /[path segment/../
555 //So first let's do a search for /../
557 iFound
=Path
.Sub(sSlashDotDotSlash
);
559 //If we've found a /./
562 //Then go back until we find the start of the path segment before it
563 INT32 iStartOfSection
=iFound
-1;
565 while (iStartOfSection
>=0 && Path
[iStartOfSection
]!=cSlash
)
568 if (iStartOfSection
>=0)
570 //Get iStartOfSection to represent the character after the slash,
571 //rather than the slash
574 //So if we've found something, then set a pointer to the end of that
576 INT32 iEndOfSection
=iFound
+3;
578 Path
.Remove(iStartOfSection
, (iEndOfSection
-iStartOfSection
+1));
581 //If we found an unparsable /../, then break now before we
582 //get into trouble...
585 //And find the next /../
586 iFound
=Path
.Sub(sSlashDotDotSlash
);
591 //No, this Web Address doesn't have a path.
592 //So it inherits the path of the base URL.
595 //If this Web Address has some parameters, we need do nothin more to it
596 if (!Parameters
.IsEmpty())
599 //Otherwise this Web Address inherits the parameters of the base URL
600 Parameters
=Base
.Parameters
;
602 //If this Web Address has a query, we need do nothin more to it
603 if (!Query
.IsEmpty())
606 //Otherwise this Web Address inherits the parameters of the base URL
609 //And that's it. (Fragments are never inherited).
613 }//End if (!Path.IsEmpty()) else...
616 //Set the "Absolute" flag to whatever it's meant to be, and return
621 /**********************************************************************************************
623 > String_256 WebAddress::GetWebAddress()
625 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
628 Returns: The full URL string
629 Purpose: Returns the URL string
631 **********************************************************************************************/
633 String_256
WebAddress::GetWebAddress()
635 String_256 strToReturn
=Scheme
;
639 strToReturn
+=Parameters
;
641 strToReturn
+=Fragment
;
649 /**********************************************************************************************
651 > BOOL WebAddress::IsHTTP()
653 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
656 Returns: TRUE if this Web Address starts with HTTP
657 Purpose: Finds whether this Web Address starts with "HTTP:"
659 **********************************************************************************************/
661 BOOL
WebAddress::IsHTTP() const
663 return (Scheme
.SubWithoutCase(String_256(_R(IDS_URL_HTTPCOLON
)))==0);
666 /**********************************************************************************************
668 > BOOL WebAddress::IsValidHTTP()
670 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
673 Returns: TRUE if this Web Address starts with HTTP and has a net location
674 Purpose: Finds whether this Web Address is a valid HTTP address.
676 We say it's a valid HTTP address if:
677 a. It starts with HTTP
678 b. It has a net location
680 Note that a valid http address may be valid but refer to a non-existent
681 network location - for example:
683 http://nonsensenonsense
685 is a valid HTTP URL that refers to a server called "nonsensenonsense", which
690 **********************************************************************************************/
692 BOOL
WebAddress::IsValidHTTP() const
694 return (IsHTTP() && !NetLocIsEmpty());
698 /**********************************************************************************************
700 > static BOOL WebAddress::IsHTTP(const String_256& strTest)
702 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
705 Returns: TRUE if strTest starts with HTTP
706 Purpose: Finds whether strTest starts with "HTTP:"
708 **********************************************************************************************/
710 BOOL
WebAddress::IsHTTP(const String_256
& strTest
)
712 WebAddress
urlTest(strTest
);
713 return (urlTest
.IsHTTP());
717 /********************************************************************************************
719 BOOL WebAddress::IsLocalFile()
721 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
726 Returns: TRUE if we consider pstrCorrect to be a local filename
729 Purpose: Works out if we consider this Web Address to be a local filename.
731 It's a local filename if its scheme is "file:"
735 SeeAlso: WebAddress::GetPathName()
737 ********************************************************************************************/
739 BOOL
WebAddress::IsLocalFile() const
741 return (Scheme
=="file:");
745 /********************************************************************************************
747 PathName WebAddress::GetPathName()
749 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
754 Returns: The PathName that is equivalent to this URL.
756 Purpose: This is used to convert a local file URL (that is, a URL
757 whose scheme is "file:") to a pathname.
759 Before calling this function, call "IsLocalFile()" to
760 make sure the scheme is "file:".
762 For example, this function converts:
764 file://d|/dir1/file.htm to d:\dir1\file.htm
766 file:////Netloc/dir1/file.htm to \\Netloc\dir1\file.htm
768 It also converts the following URLs correctly. Note that
769 these URLs are illegal - but they appear in the IE3
772 file://d:\dir1\file.htm to d:\dir1\file.htm
773 file://\\netloc\dir1\file.htm to \\netloc\dir1\file.htm
775 It does this as follows:
777 1. First, the "file:" part is removed
779 2. Then, if the net location starts with "//", that "//"
782 3. All forward slashes are converted to backslashes
784 4. All "|" characters are converted to colons
786 Of course there's no guarantee that what's left is
791 SeeAlso: WebAddress::IsLocalFile()
793 ********************************************************************************************/
795 PathName
WebAddress::GetPathName() const
797 //We needn't actually do anything to remove the Scheme - we just don't
800 //First concatenate the net location and the path
801 String_256 strToReturn
=NetLoc
;
804 //So, does that string start with "//"?
805 if (strToReturn
.Sub(String_256("//"))==0)
808 strToReturn
.Split(NULL
, &strToReturn
, 1, TRUE
);
811 //Convert all forward slashes to backslashes
812 strToReturn
.SwapChar('/', '\\');
814 //Convert all | characters to colons
815 strToReturn
.SwapChar('|', ':');
817 //Put our string into a PathName object
818 PathName
pthToReturn(strToReturn
);
826 /********************************************************************************************
828 WebAddress correction functions
830 These functions correct the URL. For example, www.xara.com might be corrected
831 to http://www.xara.com/
833 ********************************************************************************************/
835 /********************************************************************************************
837 void WebAddress::Correct(String_256* pstrCorrect, WebCorrectFlags wcfToUse)
839 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
841 Inputs: pstrCorrect - the string to correct
842 wcfToUse - a set of flags which detail how to correct
844 Outputs: pstrCorrect - the corrected string
848 Purpose: Corrects the URL string that the user has entered, according to the
853 SeeAlso: WebAddress::ApplyWebAddressToSelection; WebCorrectFlags
855 ********************************************************************************************/
857 void WebAddress::Correct(String_256
* pstrCorrect
, WebCorrectFlags wcfToUse
)
859 //If we should be correcting backslashes to forward slashes, do so now
860 if (wcfToUse
.CorrectBackslashes())
861 CorrectBackslashes(pstrCorrect
);
863 //If we should be correcting local filenames
864 if (wcfToUse
.CorrectLocalFilenames() && ShouldCorrectLocalFilenames(pstrCorrect
))
866 //Then correct it to a URL pointing to a local filename
867 CorrectLocalFilenames(pstrCorrect
);
870 //Now, if we should be correcting Netscape local URLs to IE3 ones
871 if (wcfToUse
.CorrectNetscapeFilenames() && ShouldCorrectNetscapeFilenames(pstrCorrect
))
874 CorrectNetscapeFilenames(pstrCorrect
);
876 //Otherwise if we should be correcting ftp addresses
877 else if (wcfToUse
.CorrectFTP() && ShouldCorrectFTP(pstrCorrect
))
879 //Then add "ftp:" to the front
880 CorrectFTP(pstrCorrect
);
882 //Otherwise if we should be adding http:// to the front
883 else if (wcfToUse
.CorrectHTTP() && ShouldCorrectHTTP(pstrCorrect
))
885 //Then add "http://" to the front
886 CorrectHTTP(pstrCorrect
);
889 //Otherwise if the string contains an @
890 else if (ShouldCorrectMailto(pstrCorrect
))
892 //Then add "mailto:" to the front
893 CorrectMailto(pstrCorrect
);
896 //If we should be ensuring that http addresses have a net location
897 if (wcfToUse
.CorrectNoNetLoc() && ShouldCorrectNoNetLoc(pstrCorrect
))
899 //Then add a slash to the end
900 CorrectNoNetLoc(pstrCorrect
);
904 //And finally, if we should be adding a slash to the end
905 if (wcfToUse
.CorrectNoSlash() && ShouldCorrectNoSlash(pstrCorrect
))
907 //Then add a slash to the end
908 CorrectNoSlash(pstrCorrect
);
913 /********************************************************************************************
915 void WebAddress::CorrectBackslashes(String_256* pstrCorrect)
917 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
919 Inputs: pstrCorrect - the string to correct
920 Outputs: pstrCorrect - the corrected string
924 Purpose: Corrects any backslashes in the entered string to slashes
928 SeeAlso: WebAddress::Correct()
930 ********************************************************************************************/
932 void WebAddress::CorrectBackslashes(String_256
* pstrCorrect
)
934 //Check our parameter
935 if (pstrCorrect
==NULL
)
937 ERROR2RAW("WebAddress::CorrectBackslashes - NULL parameter");
941 //And correct all backslashes to forward slashes
942 pstrCorrect
->SwapChar('\\', '/');
946 /********************************************************************************************
948 BOOL WebAddress::ShouldCorrectLocalFilenames(String_256* pstrCorrect)
950 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
952 Inputs: pstrCorrect - the string to test
955 Returns: TRUE if we consider pstrCorrect to be a local filename
958 Purpose: Works out if we consider this string to be a local filename.
960 We consider this to be a local filename if
961 a. It begins with a letter followed by a colon
962 b. It begins with \\, in which case it is a UNC pathname
966 SeeAlso: WebAddress::Correct()
968 ********************************************************************************************/
970 BOOL
WebAddress::ShouldCorrectLocalFilenames(String_256
* pstrCorrect
)
972 //Check our parameter
973 ERROR2IF(pstrCorrect
==NULL
, FALSE
, "WebAddress::CorrectBackslash - NULL parameter");
975 //If the length of the string is less than two characters, return FALSE
976 if (pstrCorrect
->Length()<2)
979 //Now, if the first character is a letter and the second character is a
981 if (StringBase::IsAlpha((*pstrCorrect
)[0]) && (*pstrCorrect
)[1]==':')
986 //Otherwise, if the first two characters are forward slashes, return TRUE
987 if ((*pstrCorrect
)[0]=='/' && (*pstrCorrect
)[1]=='/')
992 //Otherwise return FALSE
997 /********************************************************************************************
999 void WebAddress::CorrectLocalFilenames(String_256* pstrCorrect)
1001 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1003 Inputs: pstrCorrect - the string to correct
1004 Outputs: pstrCorrect - the corrected string
1008 Purpose: Assumes pstrCorrect is a local filename, then converts
1009 it to a URL referring to a local filename.
1011 It does this by calling the function PathName::GetWebAddress()
1015 SeeAlso: WebAddress::Correct(), PathName::GetWebAddress()
1017 ********************************************************************************************/
1019 void WebAddress::CorrectLocalFilenames(String_256
* pstrCorrect
)
1021 //Check our parameter
1022 if(pstrCorrect
==NULL
)
1024 ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
1029 //Now, create a pathname out of our string
1030 PathName pthTemp
=*pstrCorrect
;
1032 //And call the GetWebAddress function
1033 *pstrCorrect
=pthTemp
.GetWebAddress();
1037 /********************************************************************************************
1039 BOOL WebAddress::ShouldCorrectNetscapeFilenames(String_256* pstrCorrect)
1041 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1043 Inputs: pstrCorrect - the string to test
1046 Returns: TRUE if we consider pstrCorrect to be a Netscape local filename.
1049 Purpose: Works out if we consider this string to be a Netscape local filename.
1051 We consider this to be a Netscape local filename if it begins
1052 with "file:///", but does not begin with "file:////".
1054 The problem here is that Netscape refers to local filenames as follows:
1056 file:///d|/dir1/myname.htm
1058 But IE3 refers to local filenames as:
1060 file://d|/dir1/myname.htm
1062 Note the difference in the number of slashes. We correct it to the IE3 version.
1067 SeeAlso: WebAddress::Correct()
1069 ********************************************************************************************/
1071 BOOL
WebAddress::ShouldCorrectNetscapeFilenames(String_256
* pstrCorrect
)
1073 //Check our parameter
1074 ERROR2IF(pstrCorrect
==NULL
, FALSE
, "WebAddress::CorrectNetscapeFilenames - NULL parameter");
1076 //Set up some strings to search for
1077 String_256
strThreeSlashes("file:///");
1078 String_256
strFourSlashes("file:////");
1080 //Now, if the string begins with "file:///"...
1081 if (pstrCorrect
->SubWithoutCase(strThreeSlashes
)==0)
1083 //But the string doesn't begin with "file:////"
1084 if (pstrCorrect
->SubWithoutCase(strFourSlashes
)!=0)
1085 //Then we shoul correct it
1089 //Otherwise return FALSE
1094 /********************************************************************************************
1096 void WebAddress::CorrectNetscapeFilenames(String_256* pstrCorrect)
1098 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1100 Inputs: pstrCorrect - the string to correct
1101 Outputs: pstrCorrect - the corrected string
1105 Purpose: Converts a Netscape local filename (file:///xxxxxxx) to an IE3 local filename
1106 (file://xxxxxxx) by simply removing the third slash.
1110 SeeAlso: WebAddress::Correct(), PathName::GetWebAddress()
1112 ********************************************************************************************/
1114 void WebAddress::CorrectNetscapeFilenames(String_256
* pstrCorrect
)
1116 //Check our parameter
1117 if(pstrCorrect
==NULL
)
1119 ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
1123 //Simply delete the fifth character, removing one of the slashes
1124 pstrCorrect
->Remove(6, 1);
1128 /********************************************************************************************
1130 BOOL WebAddress::ShouldCorrectFTP(String_256* pstrCorrect)
1132 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1134 Inputs: pstrCorrect - the string to test
1137 Returns: TRUE if we consider pstrCorrect to be an ftp address
1140 Purpose: Works out if we consider this string to be a ftp address with
1143 We do so if the string starts "ftp.".
1147 SeeAlso: WebAddress::Correct()
1149 ********************************************************************************************/
1151 BOOL
WebAddress::ShouldCorrectFTP(String_256
* pstrCorrect
)
1153 //Check our parameter
1154 ERROR2IF(pstrCorrect
==NULL
, FALSE
, "WebAddress::CorrectBackslash - NULL parameter");
1156 //Are the first four characters "ftp." ?
1157 if (pstrCorrect
->SubWithoutCase(String_256("ftp."))==0)
1160 //Otherwise return FALSE
1165 /********************************************************************************************
1167 void WebAddress::CorrectFTP(String_256* pstrCorrect)
1169 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1171 Inputs: pstrCorrect - the string to correct
1172 Outputs: pstrCorrect - the corrected string
1176 Purpose: Puts "ftp:" on the start of pstrCorrect.
1180 SeeAlso: WebAddress::Correct()
1182 ********************************************************************************************/
1184 void WebAddress::CorrectFTP(String_256
* pstrCorrect
)
1186 //Check our parameter
1187 if(pstrCorrect
==NULL
)
1189 ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
1193 //If our string is over two hundred and fifty characters long, return
1194 if (pstrCorrect
->Length()>250)
1197 //Otherwise, create a new string containing "ftp://"
1198 String_256 strToReturn
="ftp://";
1200 //Add our other string onto the end of it
1201 strToReturn
+=*pstrCorrect
;
1203 //And copy our new string into our old string
1204 *pstrCorrect
=strToReturn
;
1207 /********************************************************************************************
1209 BOOL WebAddress::ShouldCorrectHTTP(String_256* pstrCorrect)
1211 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1213 Inputs: pstrCorrect - the string to test
1216 Returns: TRUE if we consider pstrCorrect to be an http address
1219 Purpose: Works out if we consider this string to be a http address with
1220 the "http:" missing.
1222 We do so if the string starts with a string of the following
1225 ;?:&=%$-_.+!*'(),abcdefghijklmnopqrstuvwxyz
1226 ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
1228 ...which contains at least two full stops. (This string
1229 of characters is taken from http://ds.internic.net/rfc/rfc1808.txt,
1230 page 4, but altered slightly).
1232 The first character should not be a full stop and there
1233 should not be two full stops together.
1237 abc-def12.gh4i3.jkl.mno
1241 SeeAlso: WebAddress::Correct()
1243 ********************************************************************************************/
1245 BOOL
WebAddress::ShouldCorrectHTTP(String_256
* pstrCorrect
)
1247 //Check our parameter
1248 ERROR2IF(pstrCorrect
==NULL
, FALSE
, "WebAddress::CorrectBackslash - NULL parameter");
1250 //Get the length of the string
1251 INT32 iLength
=pstrCorrect
->Length();
1253 //If the string is empty, return FALSE
1257 //Now, here is the set of characters to test for
1258 TCHAR
* strAllowed
=";?&=%abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$-_.+!*'(),";
1260 //If the first character is a full stop, return FALSE
1261 if ((*pstrCorrect
)[0]=='.')
1264 //And this variable will keep a count of the number of full stops
1267 //This variable will tell us if the last character we looked at
1269 BOOL fLastCharWasFullStop
=FALSE
;
1271 //Now, starting at the first character in the string, scan through
1272 //each character in turn until we get to something that is not
1273 //in our set of allowed characters
1274 for (INT32 i
=0; i
<iLength
&& (camStrchr(strAllowed
, (*pstrCorrect
)[i
]))!=NULL
; i
++)
1276 //If the letter we are looking at is a full stop,
1277 if ((*pstrCorrect
)[i
]=='.')
1279 //Then, was the last character we looked at a full stop?
1280 if (fLastCharWasFullStop
)
1282 //Yes. So we've found two full stops together. Return FALSE
1287 //No. So add one to our count of full stops and remember
1288 //that this character was a full stop
1290 fLastCharWasFullStop
=TRUE
;
1295 //No, this character is not a full stop
1296 fLastCharWasFullStop
=FALSE
;
1300 //And return true if we found more than one full stop
1301 return (iFullStops
>=2);
1305 /********************************************************************************************
1307 void WebAddress::CorrectHTTP(String_256* pstrCorrect)
1309 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1311 Inputs: pstrCorrect - the string to correct
1312 Outputs: pstrCorrect - the corrected string
1316 Purpose: Puts "http:" on the start of pstrCorrect.
1320 SeeAlso: WebAddress::Correct()
1322 ********************************************************************************************/
1324 void WebAddress::CorrectHTTP(String_256
* pstrCorrect
)
1326 //Check our parameter
1327 if(pstrCorrect
==NULL
)
1329 ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
1333 //If our string is over two hundred and fifty characters long, return
1334 if (pstrCorrect
->Length()>250)
1337 //Otherwise, create a new string containing "http:"
1338 String_256 strToReturn
="http://";
1340 //Add our other string onto the end of it
1341 strToReturn
+=*pstrCorrect
;
1343 //And copy our new string into our old string
1344 *pstrCorrect
=strToReturn
;
1347 /********************************************************************************************
1349 BOOL WebAddress::ShouldCorrectNoSlash(String_256* pstrCorrect)
1351 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1353 Inputs: pstrCorrect - the string to test
1356 Returns: TRUE if we consider that pstrCorrect is a URL to which the
1357 user has forgotten to add a trailing slash
1360 Purpose: Works out if we consider this string to be a URL with a trailing
1363 We do this by creating a Web Address object to parse the string.
1364 (Note that if this function is called, then the URL will already
1365 have had an "http://" added to the front if necessary).
1367 Then we consider that the URL should have a slash added if
1368 a. The string consists of a net location but no path
1369 (e.g. "http://www.xara.com", which should become
1370 "http://www.xara.com/")
1372 b. The path portion of the URL does not end in a slash, and
1373 the final segment of the path does not have a full stop
1376 That is, "http://www.bbc.co.uk/radio1" should have a slash
1377 added on the end, but "http://www.bbc.co.uk/index.htm" should
1383 SeeAlso: WebAddress::Correct()
1385 ********************************************************************************************/
1387 BOOL
WebAddress::ShouldCorrectNoSlash(String_256
* pstrCorrect
)
1389 //Check our parameter
1390 ERROR2IF(pstrCorrect
==NULL
, FALSE
, "WebAddress::CorrectNoSlash - NULL parameter");
1392 //First create a Web Address from our string
1393 WebAddress
urlTest(*pstrCorrect
);
1395 //Now, does the Web Address start with HTTP:, and does it have a net location
1397 if (urlTest
.IsHTTP() && !urlTest
.NetLocIsEmpty())
1401 //So, does the Web Address have an empty path?
1402 if (urlTest
.PathIsEmpty())
1404 //Yes. So we should add a slash to it.
1409 //No, there is something in the path.
1411 //So, does the path end in something other than a slash?
1412 INT32 iLength
=urlTest
.Path
.Length();
1414 if (urlTest
.Path
[iLength
-1]!='/')
1416 //Yes. So we should add a slash only if
1417 //the last segment of the path does not contain a full stop.
1419 //First try and find a slash in the path string, starting
1421 INT32 iSlashFound
=urlTest
.Path
.ReverseFind('/');
1423 //Now try and find a full stop in the path string, starting
1425 INT32 iFullStopFound
=urlTest
.Path
.ReverseFind('.');
1429 //If we didn't find a full stop, we should add a slash
1430 if (iFullStopFound
==-1)
1433 //Otherwise, we should only add a slash if the slash
1434 //was found after the full stop
1435 if (iSlashFound
>iFullStopFound
)
1438 //Otherwise, we don't add a slash
1443 //So, none of our conditions were met.
1444 //So we don't add a slash
1448 /********************************************************************************************
1450 void WebAddress::CorrectNoSlash(String_256* pstrCorrect)
1452 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1454 Inputs: pstrCorrect - the string to correct
1455 Outputs: pstrCorrect - the corrected string
1459 Purpose: Adds a slash to the end of the string
1464 SeeAlso: WebAddress::Correct(); WebAddress::ShouldCorrectNoSlash()
1466 ********************************************************************************************/
1468 void WebAddress::CorrectNoSlash(String_256
* pstrCorrect
)
1470 //Check our parameter
1471 if(pstrCorrect
==NULL
)
1473 ERROR2RAW("WebAddress::CorrectNoSlash - NULL parameter");
1477 //And if the string is long enough
1478 if (pstrCorrect
->Length()<255)
1480 //Add a slash to the end
1489 /********************************************************************************************
1491 BOOL WebAddress::ShouldCorrectMailto(String_256* pstrCorrect)
1493 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1495 Inputs: pstrCorrect - the string to test
1498 Returns: TRUE if we consider pstrCorrect to be a mail address
1501 Purpose: Works out if we consider this string to be a mail address with
1502 the "mailto:" missing.
1504 We do so if it contains an @ character and does not
1509 SeeAlso: WebAddress::Correct()
1511 ********************************************************************************************/
1513 BOOL
WebAddress::ShouldCorrectMailto(String_256
* pstrCorrect
)
1515 //Check our parameter
1516 ERROR2IF(pstrCorrect
==NULL
, FALSE
, "WebAddress::CorrectBackslash - NULL parameter");
1518 //Find the first @ symbol
1519 INT32 iLocationOfAtSymbol
=pstrCorrect
->FindNextChar('@');
1522 if (iLocationOfAtSymbol
>0)
1524 //Then check for a colon
1525 INT32 iLocationOfColon
=pstrCorrect
->FindNextChar(':');
1527 //If we didn't find one, return TRUE
1528 if (iLocationOfColon
<0)
1536 /********************************************************************************************
1538 void WebAddress::CorrectMailto(String_256* pstrCorrect)
1540 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1542 Inputs: pstrCorrect - the string to correct
1543 Outputs: pstrCorrect - the corrected string
1547 Purpose: Puts "mailto:" on the start of pstrCorrect.
1551 SeeAlso: WebAddress::Correct()
1553 ********************************************************************************************/
1555 void WebAddress::CorrectMailto(String_256
* pstrCorrect
)
1557 //Check our parameter
1558 if(pstrCorrect
==NULL
)
1560 ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
1564 //If our string is over two hundred and fifty characters long, return
1565 if (pstrCorrect
->Length()>250)
1568 //Otherwise, create a new string containing "mailto:"
1569 String_256 strToReturn
="mailto:";
1571 //Add our other string onto the end of it
1572 strToReturn
+=*pstrCorrect
;
1574 //And copy our new string into our old string
1575 *pstrCorrect
=strToReturn
;
1578 /********************************************************************************************
1580 BOOL WebAddress::ShouldCorrectNoNetLoc(String_256* pstrCorrect)
1582 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1584 Inputs: pstrCorrect - the string to test
1587 Returns: TRUE if pstrCorrect starts with "http" but does not
1588 have "//" afterwards to signify a net location
1591 Purpose: Works out if we consider this string to be an HTTP address
1592 with the "//" to signify a network location missing. For example:
1598 SeeAlso: WebAddress::Correct()
1600 ********************************************************************************************/
1602 BOOL
WebAddress::ShouldCorrectNoNetLoc(String_256
* pstrCorrect
)
1604 //Check our parameter
1605 ERROR2IF(pstrCorrect
==NULL
, FALSE
, "WebAddress::CorrectBackslash - NULL parameter");
1607 //Return TRUE if the string starts with "http:" but doesn't start with "http://"
1608 String_256
strHTTP("http:");
1609 String_256
strHTTPSlashSlash("http://");
1611 return (pstrCorrect
->SubWithoutCase(strHTTP
)==0 && pstrCorrect
->SubWithoutCase(strHTTPSlashSlash
)!=0);
1615 /********************************************************************************************
1617 void WebAddress::CorrectNoNetLoc(String_256* pstrCorrect)
1619 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
1621 Inputs: pstrCorrect - the string to correct
1622 Outputs: pstrCorrect - the corrected string
1626 Purpose: Ensures that pstrCorrect starts with "http://"
1630 SeeAlso: WebAddress::Correct()
1632 ********************************************************************************************/
1634 void WebAddress::CorrectNoNetLoc(String_256
* pstrCorrect
)
1636 //Check our parameter
1637 if(pstrCorrect
==NULL
)
1639 ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
1643 //We already know that our string does not start with "http://"
1644 //But does it start with "http:/"?
1645 if (pstrCorrect
->SubWithoutCase(String_256("http:/"))==0)
1647 //Yes it does. So insert an extra slash
1648 pstrCorrect
->Insert(&String_256("/"), 5);
1652 //No it doesn't. So insert an extra two slashes after the HTTP
1653 pstrCorrect
->Insert(&String_256("//"), 5);