00001 // $Id: pathname.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 "pathname.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00102 00103 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00104 //#include "mario.h" 00105 //#include "hotlink.h" 00106 //#include "unicdman.h" 00107 00108 //#include "resimmap.h" 00109 00110 #define MAXDRIVE 3 00111 #define MAXNAME 8 00112 #define MAXNETNAME 256 00113 #define MAXEXT 16 00114 00115 #if defined(__WXMSW__) 00116 #define SEPARATOR _T('\\') 00117 #elif defined(__WXGTK__) 00118 #define SEPARATOR _T('/') 00119 #elif defined(__WXMAC__) 00120 #define SEPARATOR _T('/') 00121 #else 00122 #error "You will need to setup the path separator for your platform" 00123 #endif 00124 00125 #define FULLSTOP '.' 00126 #define COLON ':' 00127 #define END_OF_PATH '\0' 00128 #define END_OF_STRING '\0' 00129 00130 #define SEPARATOR_SYM "\\" 00131 #define FULLSTOP_SYM "." 00132 #define COLON_SYM ":" 00133 #define END_OF_PATH_SYM "\0" 00134 #define NET_DRIVE_SYM "\\\\" 00135 00136 DECLARE_SOURCE("$Revision: 1282 $"); 00137 00138 extern void AbbreviateName(LPTSTR lpszCanon, INT32 cchMax, BOOL bAtLeastName); 00139 00140 00141 // Forward Declarations 00142 00143 BOOL getDrive(const TCHAR**, TCHAR* drive); 00144 BOOL getNetDrive(const TCHAR**, TCHAR* drive, BOOL *BadCharacter); 00145 BOOL getIdentifier(const TCHAR**, TCHAR* identifier, UINT32 MaxSize, BOOL *BadCharacter); 00146 BOOL getExtension(const TCHAR**, TCHAR* extension, UINT32 MaxSize, const TCHAR* ); 00147 BOOL getParentDirectory(const TCHAR **fn, TCHAR *directory, UINT32 MaxSize, const TCHAR * StartOfPath); 00148 BOOL IsReservedChar(const TCHAR **fn); 00149 BOOL IsDeviceName(const String_256& path); 00150 00151 00152 /********************************************************************************************** 00153 00154 > PathName::PathName() 00155 00156 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00157 Created: 12/5/93 00158 Inputs: None 00159 Outputs: None 00160 Returns: None 00161 Purpose: Default PathName class constructor 00162 Errors: None 00163 00164 **********************************************************************************************/ 00165 00166 PathName::PathName() 00167 : PathNameValid(FALSE) 00168 { 00169 // Empty. 00170 } 00171 00172 /********************************************************************************************** 00173 00174 > PathName::PathName(const PathName& newPath) 00175 00176 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00177 Created: 12/5/93 00178 Inputs: newPath 00179 Outputs: None 00180 Returns: None 00181 Purpose: Copy Constructor for the PathName class 00182 Errors: None 00183 00184 **********************************************************************************************/ 00185 00186 PathName::PathName(const PathName& other) 00187 : PathNameValid(other.PathNameValid), 00188 location(other.location), 00189 filename(other.filename), 00190 filetype(other.filetype), 00191 drivename(other.drivename) 00192 { 00193 // Empty. 00194 } 00195 00196 /********************************************************************************************** 00197 00198 > PathName::PathName(const String_256&) 00199 00200 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00201 Created: 12/5/93 00202 Inputs: String representing the path. 00203 Outputs: None 00204 Returns: None 00205 Purpose: Is to parse the path string passed in as a parameter. 00206 Also, it sets up the internal variables for location, filename and filetype. 00207 Errors: If a problem is found it will call set error with _R(IDE_PATH_ERROR) but will 00208 not call InformError as this is a contructor! 00209 00210 **********************************************************************************************/ 00211 00212 PathName::PathName(const String_256& path) 00213 { 00214 // Set up the protected variables at our disposal 00215 PathNameValid = FALSE; 00216 00217 // Check if supplied path is valid or not, if so then set up our internal variables 00218 // Use the internal form of the checking code which returns the values back to us, 00219 // blanked if a problem has happened. 00220 BOOL ok; 00221 String_256 tempFilename; //temporary string to hold the filename 00222 String_256 tempLocation; //temporary string to hold the location 00223 String_256 tempFiletype; //temporary string to hold the filetype 00224 String_256 tempDrivename; //temporary string to hold the drive name 00225 00226 // Use the internal form of the routine which returns us information which 00227 // we do not want and so just throw away 00228 ok = IsValidAndReturnInfo(path, tempFilename, tempLocation, tempFiletype, tempDrivename); 00229 00230 // We could return the result to the user but we are a constructor and so cannot. 00231 // but we will set up our variables to be the returned variables 00232 filename = tempFilename; 00233 location = tempLocation; 00234 filetype = tempFiletype; 00235 drivename = tempDrivename; 00236 PathNameValid = ok; 00237 } 00238 00239 /********************************************************************************************** 00240 00241 > const String_256 PathName::GetPath(BOOL TrailingSlash=FALSE) const 00242 00243 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> (modified for new Strings by JCF 13/8/93) 00244 (modified by Neville 25/8/94 to cope with null file types) 00245 (modified by Richard 15/2/96 for TrailingSlash biz) 00246 Created: 12/5/93 00247 Inputs: TrailingSlash - If TRUE, returned string will have a trailing '\' assigned to it... 00248 Outputs: None 00249 Returns: A Path = Location + filename + filetype 00250 Purpose: To reconstruct path name and return it. 00251 Errors: None 00252 00253 **********************************************************************************************/ 00254 00255 const String_256 PathName::GetPath(BOOL TrailingSlash) const 00256 { 00257 String_256 path; 00258 path.Empty(); 00259 00260 // Concatenation of Location, FileName and FileType 00261 path += location; 00262 path += filename; 00263 00264 // Changed by Neville 25/8/94 so that if no filetype is present then a full stop 00265 // is not added to the filename. 00266 if ( !filetype.IsEmpty() ) 00267 { 00268 path += String( wxT(FULLSTOP_SYM) ); 00269 path += filetype; 00270 } 00271 00272 // Though it might not make much sense for filenames, it's invaluable for directory paths in the 00273 // library gallery system... 00274 if(TrailingSlash) 00275 { 00276 // Add a trailing slash if it hasn't got one (usually, roots have 'em, but sub-dirs don't) 00277 INT32 ByteLength = path.Length(); 00278 PORTNOTE("other","Removed UnicodeManager usage") 00279 if( path[ByteLength-1]!=SEPARATOR ) 00280 #ifndef EXCLUDE_FROM_XARALX 00281 //|| ((path[ByteLength-1]==SEPARATOR) && UnicodeManager::IsDBCSLeadByte(path[ByteLength-2]))) 00282 #endif 00283 path += SEPARATOR; 00284 } 00285 00286 return path; 00287 } 00288 00289 /********************************************************************************************** 00290 00291 > const String_256 PathName::GetWebAddress() const 00292 00293 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00294 Created: 21/4/97 00295 Inputs: - 00296 Outputs: - 00297 Returns: The path name as a URL 00298 Purpose: This function returns the path name in URL form. 00299 00300 The resulting URL will be recognised by browsers 00301 as pointing to a local file. 00302 00303 The way we do this is: 00304 a. Convert all backslashes to forward slashes 00305 b. Add "file:///" to the start to the string 00306 00307 Remarkably, this works both with UNC pathnames and ordinary ones. So: 00308 00309 \\earth\progtemp\imagemaps/test.htm 00310 becomes 00311 file://///earth/progtemp/imagemaps/test.htm 00312 00313 d:\imagemaps\test.htm 00314 becomes 00315 file:///d:/imagemaps/test.htm 00316 00317 bugfix #10747 (Marc 20/9/04) - some browsers (notably Opera) choked on the | character 00318 when used to replace the colon in a path, so this behaviour was removed. Also, the host 00319 was not correctly specified, so it is now specified as the local machine with "file:///". 00320 00321 Notes: it was not possible to rewrite a UNC as "file://<host>/<path>" because this fails in 00322 Mozilla & Netscape. So we are left with the "file://///<host>/<path>" solution which 00323 unfortunately does not work in Opera but at least works in IE,Netscape & Mozilla! 00324 00325 Errors: None 00326 00327 **********************************************************************************************/ 00328 00329 String_256 PathName::GetWebAddress() const 00330 { 00331 //First let's get this path as a string 00332 String_256 strPath=GetPath(FALSE); 00333 00334 //Convert all the backslashes to forward slashes 00335 strPath.SwapChar('\\', '/'); 00336 00337 //Add "file:///" to the start of the sting 00338 String_256 strToReturn( wxT("file:///") ); 00339 00340 strToReturn+=strPath; 00341 00342 //And return 00343 return strToReturn; 00344 00345 } 00346 00347 00348 /********************************************************************************************** 00349 00350 > const String_256 PathName::GetTruncatedPath(UINT32 MaxSize = 0) const 00351 00352 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00353 Created: 21/3/95 00354 Inputs: MaxSize determines the maximum length of the string required. 00355 Defaults to 0 = return full path 00356 Outputs: None 00357 Returns: A Path = Location + filename + filetype which may be truncated to the specified 00358 size or less so that it can be displayed in the space required. 00359 Purpose: Display fields which require a pathname to be shown in a fixed sized space will 00360 need the path name truncated if it is too long to fit into the space. This 00361 routine should do this in the standard Microsoft way. 00362 We use an OS/MFC routine, AbbreviateName, to do the work for for us. 00363 Errors: None 00364 00365 **********************************************************************************************/ 00366 00367 const String_256 PathName::GetTruncatedPath(UINT32 MaxSize) const 00368 { 00369 // Use the normal routine to get the pathname 00370 String_256 path; 00371 path = GetPath(); 00372 00373 // Shorten the filename down a bit. 00374 String_256 ShortPath; 00375 ShortPath.Empty(); 00376 TruncateName(path, &ShortPath, (INT32)MaxSize); 00377 return ShortPath; 00378 } 00379 00380 00381 00382 00383 /******************************************************************************************** 00384 00385 > void PathName::TruncateName(String_256& FullName, String_256* pShortName, UINT32 MaxSize) 00386 00387 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00388 Created: 9/5/95 00389 Inputs: FullName - The Full Path name of the file we need to shrink 00390 MaxSize - The maximum number of characters that the path name is allowed to 00391 take up. A value of zero means infinite (ie, the whole path will be returned) 00392 Outputs: pShortName - the shortened version of the file name 00393 Purpose: This function shortens a file name, replacing the middle sections of the 00394 name with ... if needed. eg if the input path is 00395 m:\materials\graphics\artwork\myfile.art 00396 Resulting Filename MaxSize 00397 myfile.art 0-16 00398 c:\...\myfile.art 17-24 00399 c:\...\artwork\myfile.art 25-33 00400 c:\...\graphics\artwork\myfile.art 34-etc 00401 if the filename is longer than MaxSize then the filename will still be 00402 returned. In other words, it is possible for a string longer than MaxSize 00403 to be returned, so if this is important, check the length after you get 00404 your string back. 00405 00406 NOTE: Made DBCS compatiable by Peter 9/8/96 00407 00408 ********************************************************************************************/ 00409 00410 void PathName::TruncateName(String_256& FullName, String_256* pShortName, INT32 MaxSize) const 00411 { 00412 // If maxsize is zero, then give back the whole path name 00413 if (MaxSize==0) 00414 { 00415 *pShortName = FullName; 00416 return; 00417 } 00418 00419 // Find out how long the full path is 00420 INT32 FullLength = FullName.Length(); 00421 00422 // if we can fit it into MaxSize, then return it 00423 if (FullLength<=MaxSize) 00424 { 00425 *pShortName = FullName; 00426 return; 00427 } 00428 00429 // OK, we will need to compress it, so look for the actual filename part of the path 00430 // the filename goes from the end of the string to the last \ in the string 00431 const TCHAR* pFullName = (const TCHAR*)FullName; 00432 const TCHAR* pLastSlash = camStrrchr(pFullName, SEPARATOR); 00433 00434 // if we fell off the end of the string, we only had a filename, so return it 00435 if (pLastSlash == NULL) 00436 { 00437 *pShortName = FullName; 00438 return; 00439 } 00440 00441 // Find out the length of the filename 00442 INT32 FileNameLen = FullLength - (pLastSlash - pFullName); 00443 INT32 FileNameStart = pLastSlash - pFullName; 00444 00445 // Now, starting from the front of the string, we have to try and add 00446 // in more and more of the path, until it will fit no more. 00447 // We will skip the first 2 chars as they will be either c: or \\. 00448 const TCHAR* pCurrent = pFullName; 00449 pCurrent = camStrinc(pCurrent); 00450 pCurrent = camStrinc(pCurrent); // Now pointing at the third character 00451 00452 // see if this is a UNC filename 00453 if (*pCurrent != SEPARATOR) 00454 { 00455 // yes, it's UNC, so walk though the server name 00456 do 00457 { 00458 pCurrent = camStrinc(pCurrent); 00459 } while (*pCurrent != SEPARATOR); 00460 } 00461 00462 // Up to here is the volume name really 00463 INT32 VolumeNameLen = pCurrent-pFullName; 00464 00465 // and we need at least the first directory 00466 do 00467 { 00468 pCurrent = camStrinc(pCurrent); 00469 } while (*pCurrent != SEPARATOR); 00470 00471 // See if what we have will fit 00472 INT32 CurrentLength = pCurrent - pFullName; 00473 if ((CurrentLength+FileNameLen+4)>MaxSize) 00474 { 00475 // maybe we could have just volume name\...\filename 00476 if ((VolumeNameLen+4+FileNameLen)>MaxSize) 00477 { 00478 // Nope, it won't fit, so just return the filename 00479 *pShortName = String_256(pFullName+FileNameStart+1); 00480 return; 00481 } 00482 else 00483 { 00484 // Yep, we can fit it in... 00485 // Build the resulting short path 00486 FullName.Left(pShortName, VolumeNameLen); 00487 *pShortName+=TEXT(SEPARATOR_SYM) TEXT("..."); 00488 *pShortName+=pFullName+FileNameStart; 00489 return; 00490 } 00491 } 00492 00493 // Since we can fit the first directory, keep it as part of the volume name 00494 VolumeNameLen = pCurrent-pFullName; 00495 00496 // put i back to the start of the filename and start working backwards 00497 pCurrent = pFullName + FileNameStart; 00498 INT32 DirectoryStart = FileNameStart; 00499 while ((VolumeNameLen+4+(FullLength-(pCurrent-pFullName))) < MaxSize) 00500 { 00501 DirectoryStart = pCurrent-pFullName; 00502 do 00503 { 00504 pCurrent = camStrdec(pFullName, pCurrent); 00505 } while ((*pCurrent!=SEPARATOR) && ((pCurrent-pFullName)>VolumeNameLen)); 00506 } 00507 00508 // We got all the way back to the start of the volume name 00509 if (DirectoryStart==VolumeNameLen) 00510 { 00511 *pShortName = FullName; 00512 return; 00513 } 00514 00515 // Build the resulting short path 00516 FullName.Left(pShortName, VolumeNameLen); 00517 *pShortName+=TEXT(SEPARATOR_SYM) TEXT("..."); 00518 *pShortName+=pFullName+DirectoryStart; 00519 } 00520 00521 00522 00523 /********************************************************************************************** 00524 00525 > const String_256 PathName::GetTruncatedLocation(UINT32 MaxSize = 0) const 00526 00527 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00528 Created: 21/3/95 00529 Inputs: MaxSize determines the maximum length of the string required. 00530 Defaults to 0 = return full path 00531 Outputs: None 00532 Returns: A Path = Location, which may be truncated to the specified size or less so that 00533 it can be displayed in the space required. 00534 Purpose: Display fields which require a location to be shown in a fixed sized space will 00535 need the location truncated if it is too long to fit into the space. This 00536 routine should do this in the standard Microsoft way. 00537 We use an OS/MFC routine, AbbreviateName, to do the work for for us. 00538 Errors: None 00539 00540 **********************************************************************************************/ 00541 00542 const String_256 PathName::GetTruncatedLocation(UINT32 MaxSize) const 00543 { 00544 // Use the normal routine to get the pathname 00545 static String_256 path; 00546 path = GetLocation(FALSE); 00547 00548 // Shorten the filename down a bit. 00549 String_256 ShortPath; 00550 TruncateName(path, &ShortPath, (INT32)MaxSize); 00551 return ShortPath; 00552 } 00553 00554 /********************************************************************************************** 00555 00556 > const String_256 PathName::GetLocation(BOOL KeepSep = TRUE) const 00557 00558 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00559 Created: 14/3/94 00560 Inputs: KeepSep - if TRUE, it leaves the terminating backslash on the end of 00561 the location name; if FALSE, it removes it. Defaults to TRUE. 00562 Returns: The location. 00563 Purpose: To obtain the location from a pathname. 00564 00565 **********************************************************************************************/ 00566 00567 const String_256 PathName::GetLocation(BOOL KeepSep) const 00568 { 00569 String_256 path; 00570 00571 path = location; 00572 if (!KeepSep) 00573 { 00574 // Get the last character and remove it if it is a backslash. 00575 INT32 Length = path.Length() - 1; 00576 TCHAR *pLocation = (TCHAR *) path; 00577 PORTNOTE("other","Removed UnicodeManager usage") 00578 if( pLocation[Length] == SEPARATOR ) 00579 #ifndef EXCLUDE_FROM_XARALX 00580 //&& !UnicodeManager::IsDBCSLeadByte(pLocation[Length-1])) 00581 #endif 00582 pLocation[Length] = 0; 00583 } 00584 00585 return path; 00586 } 00587 00588 00589 /********************************************************************************************** 00590 00591 > const String_256 PathName::GetFileName(BOOL FullName=TRUE) const 00592 00593 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> (modified by Neville 25/8/94 to cope with null file types) 00594 Created: 12/5/93 00595 Inputs: FullName TRUE means that we are interested in the name plus extension 00596 FALSE means that we are showing the user and so the extension is not 00597 important, especially on Windows 95 (Chicago). 00598 Outputs: None 00599 Returns: FileName and FileType 00600 Purpose: To Construct the FileName out of the FileName and FileType 00601 Errors: None 00602 00603 **********************************************************************************************/ 00604 00605 const String_256 PathName::GetFileName(BOOL FullName) const 00606 { 00607 String_256 fname; 00608 fname.Empty(); 00609 00610 //Concatenation of FileName and FileType 00611 fname += filename; 00612 00613 // Changed by Neville 25/8/94 so that if no filetype is present then a full stop 00614 // is not added to the filename. 00615 // FullName parameter added 21/3/95 so that can just specify the filename itself, 00616 // without the extension. 00617 // Use IsWin32c() to test for Windows 95/Chicago 00618 if ( !filetype.IsEmpty() && FullName) 00619 { 00620 fname += String( wxT(FULLSTOP_SYM) ); 00621 fname += filetype; 00622 } 00623 00624 return fname; 00625 } 00626 00627 /********************************************************************************************** 00628 00629 > const String_256 PathName::GetType() const 00630 00631 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00632 Created: 12/5/93 00633 Inputs: None 00634 Outputs: None 00635 Returns: FileType 00636 Purpose: Extracts the file type. 00637 Errors: None 00638 00639 **********************************************************************************************/ 00640 00641 const String_256 PathName::GetType() const 00642 { 00643 return filetype; 00644 } 00645 00646 00647 00648 /******************************************************************************************** 00649 00650 > BOOL PathName::SetType(const String_256& NewType) 00651 00652 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00653 Created: 14/2/95 00654 Inputs: NewType - The new extension for the path name 00655 Returns: TRUE if it changed the extension OK 00656 Purpose: Changes the Pathnames type (extension). 00657 00658 ********************************************************************************************/ 00659 00660 BOOL PathName::SetType(const String_256& NewType) 00661 { 00662 // set the filetype to the new one 00663 filetype = NewType; 00664 00665 // all worked 00666 return TRUE; 00667 } 00668 00669 00670 /******************************************************************************************** 00671 00672 > BOOL PathName::SetFileName(const String_256& NewFileName) 00673 00674 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00675 Created: 25/06/96 00676 Inputs: NewFileName - The new filename for the path name 00677 Returns: TRUE if NewFileName is a valid file name consisting solely of the name 00678 of a file with no path delimiters, drive specification, etc. 00679 FALSE otherwise 00680 Purpose: Allow alteration of the filename component of the path 00681 00682 ********************************************************************************************/ 00683 00684 BOOL PathName::SetFileName(const String_256& NewFileName) 00685 { 00686 const TCHAR* fn = NewFileName; 00687 String_256 newfilename; 00688 BOOL BadCharacter = FALSE; 00689 BOOL ok = FALSE; 00690 ok = getIdentifier(&fn, newfilename, NewFileName.Length(), &BadCharacter); 00691 if (!ok || BadCharacter || newfilename.Length() != NewFileName.Length()) 00692 { 00693 // don't allow any bad characters & ensure given NewFileName is the whole thing 00694 return FALSE; 00695 } 00696 00697 String_32 temp; 00698 ok = getExtension(&fn, temp, MAXEXT, fn); 00699 if (ok) 00700 { 00701 // an extnesion was found - don't allow it 00702 return FALSE; 00703 } 00704 00705 // set the filename to the new one 00706 filename = newfilename; 00707 00708 return TRUE; 00709 } 00710 00711 /********************************************************************************************** 00712 00713 > BOOL PathName::SetFileNameAndType(const String_256& NewFileName) 00714 00715 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00716 Created: 10/12/96 00717 Inputs: NewFileName - String representing a filename and type 00718 Outputs: None 00719 Returns: TRUE if the filename is parsed successfully or FALSE otherwise 00720 Purpose: Parses a string representing a filename type and sets up the class 00721 variables filetype and filename if the path is valid 00722 otherwise it leaves them sets them to null strings. 00723 Always sets the filename and filetype regardless of whether there is a file 00724 type present or not. SetFileName will not set the name if there is a type present. 00725 SeeAlso: SetFileName(); 00726 Errors: None 00727 00728 **********************************************************************************************/ 00729 00730 BOOL PathName::SetFileNameAndType(const String_256& NewFileName) 00731 { 00732 // Check if supplied path is valid or not, if so then set up our internal variables 00733 // Use the internal form of the checking code which returns the values back to us, 00734 // blanked and with an error flag set if a problem has happened. 00735 BOOL ok; 00736 String_256 tempFilename; //temporary string to hold the filename 00737 String_256 tempLocation; //temporary string to hold the location 00738 String_256 tempFiletype; //temporary string to hold the filetype 00739 String_256 tempDrivename; //temporary string to hold the drive name 00740 00741 // Use the internal form of the routine which returns us information which 00742 // we do not want and so just throw away 00743 ok = IsValidAndReturnInfo(NewFileName, tempFilename, tempLocation, tempFiletype, tempDrivename); 00744 00745 // Set up our class variables to be the returned variables 00746 // Only set the ones that we are interested in though. 00747 filename = tempFilename; 00748 filetype = tempFiletype; 00749 00750 // Set up our class variable which holds this validation information 00751 PathNameValid = ok; 00752 00753 // return the result of the parsing of the pathname to the caller. 00754 return ok; 00755 } 00756 00757 /********************************************************************************************** 00758 00759 > BOOL PathName::SetPathName(const String_256&, BOOL SetErrors) 00760 00761 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00762 Created: 12/5/93 00763 Inputs: String representing a pathname and SetErrors - enables us to ignore errors. 00764 This should ONLY be false when we call this routine with an empty path 00765 (thereby ensuring that any subsequent calls to this routine (that fail) will 00766 result in an empty (but valid!) path). For an example of this, look at 00767 SGLibDisplayItem::GetFileName(PathName *Result). 00768 Outputs: None 00769 Returns: TRUE if the pathname is parsed successfully or FALSE otherwise 00770 Purpose: Parses a string representing a path and sets up the class 00771 variables filetype, filename and location if the path is valid 00772 otherwise it sets them to null strings. 00773 Errors: None 00774 00775 **********************************************************************************************/ 00776 00777 BOOL PathName::SetPathName(const String_256& path, BOOL SetErrors) 00778 { 00779 // Check if supplied path is valid or not, if so then set up our internal variables 00780 // Use the internal form of the checking code which returns the values back to us, 00781 // blanked and with an error flag set if a problem has happened. 00782 BOOL ok; 00783 String_256 tempFilename; //temporary string to hold the filename 00784 String_256 tempLocation; //temporary string to hold the location 00785 String_256 tempFiletype; //temporary string to hold the filetype 00786 String_256 tempDrivename; //temporary string to hold the drive name 00787 00788 // Use the internal form of the routine which returns us information which 00789 // we do not want and so just throw away 00790 ok = IsValidAndReturnInfo(path, tempFilename, tempLocation, tempFiletype, tempDrivename, 00791 SetErrors); 00792 00793 // Set up our class variables to be the returned variables 00794 filename = tempFilename; 00795 location = tempLocation; 00796 filetype = tempFiletype; 00797 drivename = tempDrivename; 00798 00799 // Set up our class variable which holds this validation information 00800 PathNameValid = ok; 00801 00802 // return the result of the parsing of the pathname to the caller. 00803 return ok; 00804 } 00805 00806 /********************************************************************************************** 00807 00808 > BOOL PathName::IsValid(const String_256&) const 00809 00810 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00811 Created: 12/5/93 00812 Inputs: String representing a pathname 00813 Outputs: None 00814 Returns: TRUE if the pathname is parsed successfully or FALSE otherwise 00815 Purpose: Parses a string representing a path and sets up the class 00816 variables filetype, filename and location if the path is valid. 00817 Cannot do the usual 8.3 checking of things like filenames as this is no longer 00818 valid given Chicargo and NT non-FAT filing systems. 00819 Errors: If it fails then it will call set error with the error found. 00820 00821 **********************************************************************************************/ 00822 /* 00823 Technical notes: 00824 We used to do explicit checking of 8.3 filenames, correct letters being used in all filenames 00825 and directory names but unfortunately we did not cope with things like long directory names, 00826 spaces in filenames and directory names, relative paths. Unfortunately, there is no nice 00827 operating system routine to do this checking for us so all we can do is some basic checking of 00828 validity like a null path being specified, bad names such as d:\ and \\blobby. A lot of the 00829 time the data being passed to us has been validated by the Common Dialogs for open and save. 00830 00831 **********************************************************************************************/ 00832 00833 BOOL PathName::IsValid(const String_256& path) const 00834 { 00835 BOOL ok; 00836 String_256 tempFilename; //temporary string to hold the filename 00837 String_256 tempLocation; //temporary string to hold the location 00838 String_256 tempFiletype; //temporary string to hold the filetype 00839 String_256 tempDrivename; //temporary string to hold the drive name 00840 00841 // Use the internal form of the routine which returns us information which 00842 // we do not want and so just throw away 00843 ok = IsValidAndReturnInfo(path, tempFilename, tempLocation, tempFiletype, tempDrivename); 00844 00845 // Set up our class variable which holds this validation information 00846 //PathNameValid = ok; // don't be so stupid 00847 00848 // return result to the user 00849 return ok; 00850 } 00851 00852 /********************************************************************************************** 00853 00854 > BOOL PathName::IsValid() const 00855 00856 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00857 Created: 7/3/95 00858 Inputs: None 00859 Outputs: None 00860 Returns: TRUE if the present pathname has been parsed successfully or FALSE otherwise 00861 Purpose: Says whether the pathname currently in the class has been parsed correctly. 00862 This should only be used if the non-blank contructors have been called and more 00863 specifically the contructor which takes a pathname as a parameter has been used. 00864 This function then returns the result of the validation that happens in the 00865 constructor as of course constructors cannot return results! 00866 SeeAlso: PathName::IsValid(const String_256& path); 00867 Errors: If it fails then it will call set error with the error found. 00868 00869 **********************************************************************************************/ 00870 00871 BOOL PathName::IsValid() const 00872 { 00873 // Just return the result that we have found earlier to the caller 00874 // If the wrong constructor has been called then should be automatically FALSE. 00875 return PathNameValid; 00876 } 00877 00878 00879 00880 00881 /********************************************************************************************** 00882 00883 > virtual BOOL PathName::IsValidAndReturnInfo(const String_256& ConstPath, String_256& tempFilename, 00884 String_256& tempLocation, String_256& tempFiletype, String_256& tempDrivename, BOOL SetErrors = TRUE) const 00885 00886 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (with updated function protocol comments by Richard !) 00887 Created: 12/5/93 00888 00889 Inputs: ConstPath - String representing the pathname to check 00890 SetErrors - Flag to say whether we should set errors or not (defaults to TRUE) 00891 00892 Outputs: tempFilename - String representing the filename 00893 tempLocation - String representing the location 00894 tempFiletype - String representing the filetype 00895 tempDrivename - String representing the drive name 00896 00897 Returns: TRUE if the pathname is parsed successfully or FALSE otherwise 00898 Purpose: Parses a string representing a path and returns the filetype, filename 00899 and location to the caller if the path is valid. 00900 Cannot do the usual 8.3 checking of things like filenames as this is no longer 00901 valid given Chicago and NT non-FAT filing systems. 00902 Routine called by IsValid to actually go and do the work involved with 00903 checking the pathname. Done this way so that internal calls do not have to 00904 parse the data again to get at the variables. 00905 Errors: If it fails then it will call set error with the error found. 00906 This can now be supressed if required. 00907 00908 **********************************************************************************************/ 00909 00910 BOOL PathName::IsValidAndReturnInfo(const String_256& ConstPath, 00911 String_256& tempFilename, 00912 String_256& tempLocation, 00913 String_256& tempFiletype, 00914 String_256& tempDrivename, 00915 BOOL SetErrors) const 00916 { 00917 // First ensure the strings passed in are blanked 00918 tempFilename.Empty(); 00919 tempLocation.Empty(); 00920 tempFiletype.Empty(); 00921 tempDrivename.Empty(); 00922 00923 // Get a non const version, as this function tends to party a bit too much 00924 String_256 path = ConstPath; 00925 00926 // Then check for an empty path being passed to us 00927 // and also that a device name is not being specified 00928 if ( !path.IsEmpty() && !IsDeviceName(path)) 00929 { 00930 BOOL ok = TRUE; // General flag for returning results 00931 BOOL driveFound = FALSE; // Flag for valid drive found 00932 BOOL fnameFound = FALSE; // Flag for valid filename found 00933 BOOL BadCharacter = FALSE; // Flag for bad character found 00934 00935 String_256 temp; // temporary string buffer 00936 String_256 tempDrive; // temporary string to hold drive 00937 00938 const TCHAR *fn; // File Name Pointer 00939 00940 fn = path; 00941 temp.Empty(); 00942 00943 // First check if there is a valid drive name or net drive name present 00944 // If the first character of the path is an alpha then assume drive and check if valid 00945 // and so of the form D:/ 00946 // Otherwise, check for a UNC (Universal naming convention) form of drive of the form 00947 // \\Deepthought 00948 if (*fn == SEPARATOR) 00949 driveFound = getNetDrive(&fn, temp, &BadCharacter); //Parse as UNC or network drive 00950 else 00951 driveFound = getDrive(&fn, temp); // Parse the Drive 00952 00953 // If parsed that ok then add the drive to our location store 00954 // otherwise reset back to the entire path string and look for a relative style path 00955 if (driveFound) 00956 { 00957 tempLocation = temp; // Add drive to location string 00958 tempDrivename = temp; // Note drive name found for future use 00959 } 00960 else 00961 fn = path; // Start again at first character 00962 00963 // If no drive or net drive (UNC) present then this may be a relative path so do not 00964 // assume that everything fails because of this. 00965 // Now move along the path to see if we have a correct filename with possible multiple 00966 // directories being specified before it. 00967 while (ok && !fnameFound) 00968 { 00969 temp.Empty(); // Clear temporary 00970 // The size of the file/directory name is really max string size - current size 00971 // of the location string i.e. the space remaining in our fixed length strings. 00972 UINT32 MaxSize = temp.MaxLength() - tempLocation.Length(); 00973 ok = getIdentifier(&fn, temp, MaxSize, &BadCharacter); //Get the Identifier 00974 if (ok) 00975 { 00976 if (*fn == SEPARATOR) // If it is a directory location\path 00977 { 00978 tempLocation += temp; // add to file location\path temp buffer 00979 fn++; // and move to after separator 00980 } 00981 else // If it is a filename 00982 { 00983 tempFilename = temp; // add to file name temp buffer 00984 fnameFound = TRUE; // and flag found to terminate search 00985 } 00986 } 00987 } 00988 00989 // If everything went well then we should now have a filename with an optional 00990 // drive/net drive and optional directory list. Now check for a file extension 00991 // on the end of the filename. 00992 // fn is pointing at the end of the found filename if everything ok 00993 00994 if (ok) // If ok so far 00995 { 00996 // Note current position i.e. end of supplied path 00997 // We will scan from the end backwards to locate the extension. 00998 // const TCHAR* CurrentPos = fn; 00999 const TCHAR* StartOfPath = path; 01000 01001 if (*fn == END_OF_PATH || *fn == END_OF_STRING) 01002 { 01003 fn = camStrdec(path, fn); // move to last valid character 01004 // Get File Extension 01005 // If we don't find a vlaid extension then do not complain as this should 01006 // not be a problem. 01007 BOOL ExtOk = getExtension(&fn, temp, MAXEXT, StartOfPath); 01008 01009 if (ExtOk) 01010 { 01011 // We parsed it ok, so make a note of it. 01012 tempFiletype = temp; // FileType = File Extension 01013 // tempFileName should already be = leafname found 01014 // tempLocation should already be = directory path found 01015 // And remove it from the filename 01016 UINT32 LenFilename = tempFilename.Length(); 01017 UINT32 LenExtensionName = tempFiletype.Length(); 01018 // Strip the extension name plus the full stop from the filename. 01019 if (LenFilename > LenExtensionName) 01020 { 01021 temp.Empty(); 01022 tempFilename.Left(&temp, (LenFilename - LenExtensionName - 1)); 01023 tempFilename = temp; 01024 } 01025 } 01026 else 01027 { 01028 // We have not found what we consider to be a valid extension so say 01029 // we have a blank filetype. 01030 tempFiletype.Empty(); // FileType = File Extension 01031 // The filename is the valid leafname that has been found, possibly 01032 // including a dodgy extension name that we did not like at all. 01033 } 01034 } 01035 else 01036 { 01037 tempFiletype.Empty(); // FileType = File Extension = none 01038 } 01039 } 01040 01041 // Ok is the flag that says whether we have found a valid filename or not so return 01042 // this to the caller. 01043 // Now we also have a flag BadCharacter. If set we have found what we consider to be 01044 // an illegal/reserved character in the filename and so should return false but may 01045 // have parsed the filename ok so that this can be shown to the user. 01046 // if (BadCharacter) 01047 // { 01048 // // If set errors has been specified then set up the required error 01049 // if (SetErrors) 01050 // Error::SetError(_R(IDE_PATH_ERROR), 0); // Set up the correct error 01051 // return FALSE; 01052 // } 01053 // else 01054 // return ok; // Return ok flag 01055 01056 // Always return the result, if we reach this point. Ignore bad characters as these 01057 // are ok under NT. 01058 if (!ok) 01059 { 01060 if (SetErrors) 01061 { 01062 Error::SetError(_R(IDE_PATH_ERROR), 0); 01063 } 01064 } 01065 return ok; 01066 } 01067 else 01068 { 01069 tempFiletype.Empty(); //Return blank fileType 01070 tempFilename.Empty(); //Return blank fileName 01071 tempLocation.Empty(); //Return blank location 01072 01073 // If set errors has been specified then set up the required error 01074 if (SetErrors) 01075 Error::SetError(_R(IDE_PATH_ERROR), 0); // Set up the correct error 01076 return FALSE; // Null path passed to us 01077 } 01078 01079 // If we reach here then things must have gone terribly wrong so return False 01080 return FALSE; 01081 } 01082 01083 01084 /********************************************************************************************** 01085 01086 > PathName& PathName::operator=(const PathName& newPath) 01087 01088 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 01089 Created: 31/8/93 01090 Inputs: newPath 01091 Outputs: None 01092 Returns: PathName 01093 Purpose: Assignment operator for pathnames. 01094 Errors: None 01095 01096 **********************************************************************************************/ 01097 01098 PathName& PathName::operator=(const PathName& newPath) 01099 { 01100 filename = newPath.filename; 01101 location = newPath.location; 01102 filetype = newPath.filetype; 01103 drivename = newPath.drivename; 01104 01105 PathNameValid = newPath.PathNameValid; 01106 01107 return *this; 01108 } 01109 01110 01111 /********************************************************************************************** 01112 Win16 Path String Parser Functions 01113 01114 **********************************************************************************************/ 01115 01116 /********************************************************************************************** 01117 01118 > BOOL getDrive(TCHAR **fn, TCHAR *drive) 01119 01120 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 01121 Created: 12/5/93 01122 Inputs: A pointer to the pointer to the path string 01123 Outputs: drive - the parsed Drive Letter 01124 Returns: TRUE if parsed ok and false otherwise 01125 Purpose: Parses the Drive location of file. 01126 Scope: Private 01127 SeeAlso: PathName(); 01128 SeeAlso: SetPath(); 01129 Errors: None 01130 01131 **********************************************************************************************/ 01132 01133 BOOL getDrive(const TCHAR **fn, TCHAR *drive) 01134 { 01135 UINT32 i = 0; 01136 01137 if (String::IsAlpha(**fn)) 01138 { 01139 drive[i++] = **fn; // Parse Drive Letter 01140 (*fn)++; 01141 if (**fn == COLON) // Parse colon 01142 { 01143 drive[i++] = **fn; 01144 (*fn)++; 01145 if (**fn == SEPARATOR) // Parse slash 01146 { 01147 drive[i++] = **fn; 01148 (*fn)++; 01149 } 01150 else 01151 return FALSE; // Else Syntax error 01152 } 01153 else 01154 return FALSE; 01155 } 01156 else 01157 return FALSE; 01158 01159 drive[i++] = END_OF_STRING; 01160 01161 return TRUE; 01162 } 01163 01164 /********************************************************************************************** 01165 01166 > BOOL getNetDrive(TCHAR **fn, TCHAR *drive, BOOL *BadCharacter) 01167 01168 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 01169 Created: 3/9/93 01170 Inputs: A pointer to the pointer to the path string 01171 A pointer to the current bad character flag state 01172 Outputs: A network drive Letter 01173 A pointer to the potentially new bad character flag state 01174 Returns: TRUE if parsed ok FALSE otherwise 01175 Purpose: Parses the network Drive location of file and returns whether this was 01176 accomplished or not. 01177 The network name will consist of the server name followed by a mount point name. 01178 Scope: Private 01179 SeeAlso: PathName(); 01180 SeeAlso: SetPath(); 01181 Errors: None 01182 01183 **********************************************************************************************/ 01184 01185 BOOL getNetDrive(const TCHAR **fn, TCHAR *drive, BOOL *pBadCharacter) 01186 { 01187 // Used for storing either <ServerName> or <DirectoryName> 01188 String_256 identifier; 01189 TCHAR* pId; 01190 01191 UINT32 i = 0; 01192 01193 if (**fn == SEPARATOR) // Parse '\\' bit 01194 { 01195 drive[i++] = **fn; 01196 01197 (*fn)++; 01198 01199 if (**fn == SEPARATOR) 01200 { 01201 01202 drive[i++] = **fn; 01203 01204 (*fn)++; 01205 01206 identifier.Empty(); 01207 01208 // We have a valid network name start 01209 // Parse Network drive name(s) 01210 if ( getIdentifier(&(*fn), identifier, MAXNETNAME, pBadCharacter) ) 01211 { 01212 pId = identifier; // Copy identifier into drive 01213 01214 while (*pId != END_OF_STRING) 01215 { 01216 drive[i++] = *pId; 01217 pId++; 01218 } 01219 01220 (*fn)++; 01221 01222 identifier.Empty(); 01223 01224 // We have a valid network drive name and so parse the mount point name 01225 if ( getIdentifier(&(*fn), identifier, MAXNETNAME, pBadCharacter) ) 01226 { 01227 pId = identifier; // Copy identifier into drive 01228 01229 while (*pId != END_OF_STRING) 01230 { 01231 drive[i++] = *pId; 01232 pId++; 01233 } 01234 01235 (*fn)++; 01236 01237 drive[i++] = END_OF_STRING; 01238 01239 // Everything has gone ok so now exit 01240 return TRUE; 01241 } 01242 else 01243 return FALSE; 01244 } 01245 else 01246 return FALSE; 01247 } 01248 else 01249 return FALSE; 01250 } 01251 else 01252 return FALSE; 01253 } 01254 01255 // Forward Declaration 01256 01257 //BOOL IsSpecialChar(TCHAR **fn); 01258 01259 /********************************************************************************************** 01260 01261 > BOOL getIdentifier(TCHAR **fn, TCHAR *identifier, UINT32 MaxSize, BOOL *BadCharacter) 01262 01263 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 01264 Created: 12/5/93 01265 Inputs: A pointer to the pointer to the path string 01266 MaxSize - the maximum size of a network drive name 01267 A pointer to the current bad character flag 01268 Outputs: A file or directory identifier 01269 A pointer to a potentially new state of the bad character flag which signals 01270 a bad/reserved character was found in the string 01271 Returns: TRUE if parsed ok FALSE otherwise 01272 Purpose: Parses file or directory identifier 01273 Scope: Private 01274 SeeAlso: PathName(); 01275 SeeAlso: SetPath(); 01276 Errors: None 01277 01278 **********************************************************************************************/ 01279 01280 BOOL getIdentifier(const TCHAR **fn, TCHAR *identifier, UINT32 MaxSize, BOOL *pBadCharacter) 01281 { 01282 UINT32 i = 0; 01283 01284 // While not a Separator or not EOF or Maximum size 01285 // Used to check for (String::IsAlphaNumeric(**fn) || IsSpecialChar(fn)) 01286 // to see if it was a valid character or not but this would not allow things like 01287 // spaces which are allowed under NT and Chicago. Reduce check to known problem 01288 // characters such as colons in the wrong place and '/'. 01289 // but must only flag this as an error and continue as we must have a filename at the 01290 // end so that a m4essage such as 'cannot open file: xxxxx.xx' can be shown by using 01291 // the GetFileName call. 01292 // Removed the FULLSTOP test as this was stopping directory names having full stops in 01293 01294 while ( **fn != SEPARATOR && // If not a separator for next directory/filename 01295 **fn != END_OF_PATH && // and not terminator 01296 i < (MaxSize)) // is less than maximum name size 01297 { 01298 // Check if this is an illegal character for the filing system and if so 01299 // make a note and continue. 01300 if ( IsReservedChar(fn) ) 01301 { 01302 *pBadCharacter = TRUE; // Flag bad character found 01303 } 01304 01305 identifier[i++] = **fn; // Parse the Identifier 01306 (*fn)++; 01307 } 01308 01309 // if a valid identifier terminator found then return True 01310 // otherwise return False. 01311 // Do not stop on full stops as these are valid in directory names. 01312 if (**fn == SEPARATOR || 01313 **fn == END_OF_PATH) 01314 { 01315 if (**fn == SEPARATOR) 01316 { 01317 identifier[i++] = **fn; // Parse the Separator 01318 } 01319 01320 identifier[i++] = END_OF_STRING; // Set end of string 01321 01322 return TRUE; 01323 } 01324 else 01325 return FALSE; 01326 } 01327 01328 /********************************************************************************************** 01329 01330 > BOOL getExtension(TCHAR **fn, TCHAR *ext, UINT32 MaxSize, const TCHAR * StartOfPath) 01331 01332 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 01333 Created: 12/5/93 01334 Inputs: A pointer to the pointer to the path string 01335 MaxSize - the maximum size of a network drive name 01336 StartOfPath - a pointer to the start of the path string 01337 Outputs: A file extension 01338 Returns: TRUE if parsed ok FALSE otherwise 01339 Purpose: Parses from the specified position, which should be the last valid character on 01340 the pathname, backwards until we hit either:- 01341 - a full stop, in which case we have a valid filename extension, which we return 01342 - a path separator, in which case there is no extension 01343 - the start of the pathname, in which case there is no extension. 01344 Scope: Private 01345 SeeAlso: PathName(); IsValidAndReturnInfo(); SetPath(); 01346 Errors: None 01347 01348 **********************************************************************************************/ 01349 01350 BOOL getExtension(const TCHAR **fn, TCHAR *ext, UINT32 MaxSize, const TCHAR * StartOfPath) 01351 { 01352 UINT32 i = 0; 01353 01354 // Search from the specified string end backwards until we find either:- 01355 // - a full stop indicating a valid extension 01356 // - a path separator indicating no file extension is present 01357 // - the start of the file indicating no file extension is present 01358 while ( 01359 (**fn != SEPARATOR) && // is not at a path separating character 01360 (**fn != FULLSTOP) && // is not at a full stop character 01361 (*fn != StartOfPath) && // is not at the start of the path string 01362 (i < MaxSize) // is not maximum size 01363 ) 01364 { 01365 i++; 01366 (*fn)--; 01367 } 01368 01369 if (**fn != FULLSTOP) // if we are not at a full stop Then Syntax error 01370 return FALSE; 01371 01372 // Make up the string that we are going to return 01373 // Do it this way as otherwise we would be adding the characters in backwards in the above 01374 // routine as we are scanning backwards! 01375 UINT32 position = 0; // Start at first character in the string 01376 (*fn)++; // Move to character after the full stop 01377 while (( i >= 0 ) && (**fn != END_OF_PATH)) 01378 { 01379 ext[position++] = **fn; // Add current character to File Extension 01380 (*fn)++; // Move to next character 01381 i--; // decrement extension letters count 01382 } 01383 01384 ext[position++] = END_OF_STRING; // Set end of string 01385 01386 return TRUE; 01387 } 01388 01389 /********************************************************************************************** 01390 01391 > BOOL getParentDirectory(TCHAR **fn, TCHAR *ext, UINT32 MaxSize) 01392 01393 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01394 Created: 21/3/95 01395 Inputs: A pointer to the pointer to the path string 01396 MaxSize - the maximum size of a network drive name 01397 StartOfPath - a pointer to the start of the path string 01398 Outputs: The parent directory name 01399 Returns: TRUE if parsed ok FALSE otherwise 01400 Purpose: Parses from the specified position, which should be something like the first valid 01401 character of the filename on the pathname, backwards until we hit either:- 01402 - a path separator, in which case we return the found name as a possible directory 01403 - the start of the pathname, in which case there is no directory name. 01404 Scope: Private 01405 SeeAlso: GetTruncatedPath(); 01406 Errors: None 01407 01408 **********************************************************************************************/ 01409 01410 BOOL getParentDirectory(const TCHAR **fn, TCHAR *directory, UINT32 MaxSize, const TCHAR * StartOfPath) 01411 { 01412 UINT32 i = 0; 01413 01414 // Note where we are in the path 01415 const TCHAR* CurrentPosition = *fn; 01416 01417 // If we are tsarting on a separator then skip it 01418 if (**fn == SEPARATOR) 01419 (*fn)--; 01420 01421 // Search from the specified string end backwards until we find either:- 01422 // - a path separator indicating we have found a potential parent directory. 01423 // - the start of the file indicating no parent directory is present 01424 while ( 01425 (**fn != SEPARATOR) && // is not at a path separating character 01426 (*fn != StartOfPath) && // is not at the start of the path string 01427 (i < MaxSize) // is not maximum size 01428 ) 01429 { 01430 i++; 01431 (*fn)--; 01432 } 01433 01434 if (**fn != SEPARATOR) // if we are not at a directory separator 01435 return FALSE; // Then Syntax error 01436 01437 // Make up the string that we are going to return 01438 // Do it this way as otherwise we would be adding the characters in backwards in the above 01439 // routine as we are scanning backwards! 01440 UINT32 position = 0; // Start at first character in the string 01441 while (( i >= 0 ) && (*fn != CurrentPosition)) 01442 { 01443 directory[position++] = **fn; // Add current character to directory name 01444 (*fn)++; // Move to next character 01445 i--; // decrement directory name letters count 01446 } 01447 01448 directory[position++] = END_OF_STRING; // Set end of string 01449 01450 return TRUE; 01451 } 01452 01453 01454 /********************************************************************************************** 01455 01456 > BOOL IsSpecialChar(const TCHAR **fn) 01457 01458 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 01459 Created: 14/10/93 01460 Inputs: A pointer to the pointer to the path string 01461 Outputs: None 01462 Returns: True if character is a special char allowed in filenames and False otherwise 01463 Purpose: Checks if character passed in is a special character allowed in file names. 01464 No longer used. 01465 Scope: Private 01466 SeeAlso: PathName(); 01467 Errors: None 01468 01469 **********************************************************************************************/ 01470 01471 // Function no longer required 01472 //BOOL IsSpecialChar(TCHAR **fn) 01473 //{ 01474 // const TCHAR UNDERSCORE = '_'; 01475 // const TCHAR HAT = '^'; 01476 // const TCHAR DOLLAR = '$'; 01477 // const TCHAR EXCLAMATION = '!'; 01478 // const TCHAR HASH = '#'; 01479 // const TCHAR PERCENT = '%'; 01480 // const TCHAR AMPESAND = '&'; 01481 // const TCHAR MINUS = '-'; 01482 // const TCHAR OPENCURLY = '{'; 01483 // const TCHAR CLOSEDCURLY = '}'; 01484 // const TCHAR OPENBRAC = '('; 01485 // const TCHAR CLOSEDBRAC = ')'; 01486 // const TCHAR ATSIGN = '@'; 01487 // const TCHAR INVERTCOMMA = '`'; 01488 // 01489 // if ((**fn != UNDERSCORE) && 01490 // (**fn != HAT) && 01491 // (**fn != DOLLAR) && 01492 // (**fn != EXCLAMATION) && 01493 // (**fn != HASH) && 01494 // (**fn != PERCENT) && 01495 // (**fn != AMPESAND) && 01496 // (**fn != MINUS) && 01497 // (**fn != OPENCURLY) && 01498 // (**fn != CLOSEDCURLY) && 01499 // (**fn != OPENBRAC) && 01500 // (**fn != CLOSEDBRAC) && 01501 // (**fn != ATSIGN) && 01502 // (**fn != INVERTCOMMA)) 01503 // return FALSE; 01504 // else 01505 // return TRUE; 01506 //} 01507 01508 /********************************************************************************************** 01509 01510 > BOOL IsReservedChar(const TCHAR **fn) 01511 01512 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01513 Created: 29/08/94 01514 Inputs: A pointer to the pointer to the path string 01515 Outputs: None 01516 Returns: True if the character is a reserved character not allowed in filenames 01517 and False otherwise 01518 Purpose: Checks if character passed in is a reserved character allowed in file names. 01519 Does not check for terminators which are allowed by the callers such as . 01520 and backslash. These characters are considered illegal when converting long to 01521 short filenames and so it would seem sensible to limit their use. 01522 Scope: Private 01523 SeeAlso: PathName(); 01524 Errors: None 01525 01526 **********************************************************************************************/ 01527 01528 BOOL IsReservedChar(const TCHAR **fn) 01529 { 01530 const TCHAR SLASH = '/'; 01531 const TCHAR OPENSQUARE = '['; 01532 const TCHAR CLOSESQUARE = ']'; 01533 const TCHAR QUOTES = '"'; 01534 const TCHAR COLON_TCHAR = ':'; 01535 const TCHAR SEMICOLON = ';'; 01536 const TCHAR COMMA = ','; 01537 const TCHAR EQUALS = '='; 01538 01539 if ((**fn != SLASH) && 01540 (**fn != OPENSQUARE) && 01541 (**fn != CLOSESQUARE) && 01542 (**fn != QUOTES) && 01543 (**fn != COLON_TCHAR) && 01544 (**fn != SEMICOLON) && 01545 (**fn != COMMA) && 01546 (**fn != EQUALS)) 01547 return FALSE; 01548 else 01549 return TRUE; 01550 } 01551 01552 01553 /********************************************************************************************** 01554 01555 > BOOL IsDeviceName(const String_256& path) 01556 01557 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01558 Created: 12/5/93 01559 Inputs: String representing a pathname 01560 Outputs: None 01561 Returns: TRUE if the pathname is a device name or FALSE otherwise. 01562 Purpose: Parses a string representing a path and sees if it refers to 01563 a device name which would be illegal. 01564 Errors: None 01565 01566 **********************************************************************************************/ 01567 01568 BOOL IsDeviceName(const String_256& path) 01569 { 01570 #if defined(__WXMSW__) 01571 const INT32 buffer_size = 256; 01572 TCHAR buffer[buffer_size]; // create buffer of characters 01573 // First use a Windows call to try and see if the pathname supplied is a 01574 // known device name. Use a 256 string as a buffer as not particular bothered 01575 // by what is returned, only if something is returned 01576 DWORD i; 01577 i = QueryDosDevice(path, buffer, buffer_size); // See if known Windows device name 01578 01579 // returns i = number of characters supplied in pBuffer, if 0 then failed 01580 //TRACE( _T("QueryDosDevice returns %d\n"),i); 01581 if (i>0) 01582 return TRUE; // valid device name, therefore passes 01583 #endif 01584 01585 // Check our pathname against some known basic names as a final check 01586 // Device names will in general have three letters with a possible number 01587 // and possible colon on the end. 01588 String_256 temp; // general workspace string 01589 01590 // work out in temp the left most three characters and then compare this with 01591 // some known bad values 01592 path.Left(&temp,4); // temp = left most 4 characters of path 01593 01594 if ( temp.IsIdentical(TEXT(SEPARATOR_SYM) TEXT(SEPARATOR_SYM) TEXT(".") TEXT(SEPARATOR_SYM))) // NT device name starts with this 01595 return TRUE; // if start this then no more checks required 01596 01597 path.Left(&temp,3); // temp = left most 3 characters of path 01598 temp.toUpper(); // Now convert to upper case 01599 01600 if ( (temp.IsIdentical(TEXT("LPT"))) || // basic DOS print device 01601 (temp.IsIdentical(TEXT("COM"))) || // basic DOS communication port 01602 (temp.IsIdentical(TEXT("NUL"))) || // basic DOS null device 01603 (temp.IsIdentical(TEXT("AUX")))) // basic DOS auxiliary port 01604 { 01605 // Check that the length of the name is correct i.e. 3, 4 or 5 long 01606 const TCHAR *dn; // device name pointer 01607 dn = path; // set to point to the current path 01608 01609 switch (path.Length()) 01610 { 01611 case 3: 01612 // correct length and passed the test above so its a device name 01613 // drop through to after case and return True 01614 break; 01615 01616 case 4: 01617 // check for number or a colon on the end 01618 // position is from 0.. and so want character number 3 01619 dn += 3; // point to third character in name 01620 if ( ( !String::IsNumeric(*dn) ) && ( *dn != COLON ) ) 01621 return FALSE; // not colon or number 01622 // drop through to after case and return True 01623 break; 01624 01625 case 5: 01626 // check for number and colon on the end 01627 // position is from 0.. and so want character number 3 01628 dn += 3; // point to third character in name 01629 // first check that the second to last character is a number 01630 if ( !String::IsNumeric(*dn) ) 01631 return FALSE; // not a number so return False 01632 // now check that the last character is a colon 01633 dn += 1; // move to last character 01634 if ( *dn != COLON ) 01635 return FALSE; // not a colon so return False 01636 // drop through to after case and return True 01637 break; 01638 01639 default: 01640 // In all other cases can return False as wrong length 01641 return FALSE; 01642 break; 01643 } // end switch 01644 return TRUE; // passed above tests so return True 01645 } 01646 else 01647 return FALSE; // failed in three letter comparisons so not a recognised device 01648 } 01649 01650 01651 01652 01653 /********************************************************************************************** 01654 01655 > DirPath::DirPath() 01656 DirPath::DirPath(const DirPath& newPath) 01657 DirPath::DirPath(const String_256& path) 01658 01659 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 01660 Created: 6/2/96 01661 Purpose: DirPath class constructors 01662 01663 **********************************************************************************************/ 01664 01665 DirPath::DirPath() : PathName() 01666 { 01667 } 01668 DirPath::DirPath(const DirPath& newPath) : PathName(newPath) 01669 { 01670 } 01671 DirPath::DirPath(const String_256& path) : PathName(path) 01672 { 01673 } 01674 01675 /********************************************************************************************** 01676 01677 > BOOL DirPath::SetDirPath(const String_256& path) 01678 01679 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 01680 Created: 6/2/96 01681 Inputs: path - String representing a pathname 01682 Returns: TRUE if the directory pathname is parsed successfully or FALSE otherwise 01683 Purpose: Parses a string representing a path and sets up the class 01684 variables filetype, filename and location if the path is valid 01685 otherwise it sets them to null strings. 01686 Errors: None 01687 01688 **********************************************************************************************/ 01689 01690 BOOL DirPath::SetDirPath(const String_256& path) 01691 { 01692 return PathName::SetPathName(path); 01693 } 01694 01695 /********************************************************************************************** 01696 01697 > virtual BOOL DirPath::IsValid(const String_256& path) const 01698 01699 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 01700 Created: 6/2/96 01701 Inputs: path - String representing a pathname 01702 Returns: TRUE if the directory pathname is parsed successfully or FALSE otherwise 01703 Purpose: Parses a string representing a directory path and sets up the class 01704 variables filetype, filename and location if the path is valid. 01705 Cannot do the usual 8.3 checking of things like filenames as this is no longer 01706 valid given Chicago and NT non-FAT filing systems. 01707 Errors: If it fails then it will call set error with the error found. 01708 01709 **********************************************************************************************/ 01710 01711 BOOL DirPath::IsValid(const String_256& path) const 01712 { 01713 return PathName::IsValid(path); 01714 } 01715 01716 /********************************************************************************************** 01717 01718 > virtual BOOL DirPath::IsValid() const 01719 01720 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 01721 Created: 6/2/96 01722 Returns: TRUE if the present pathname has been parsed successfully or FALSE otherwise 01723 Purpose: Says whether the pathname currently in the class has been parsed correctly. 01724 This should only be used if the non-blank contructors have been called and more 01725 specifically the contructor which takes a pathname as a parameter has been used. 01726 This function then returns the result of the validation that happens in the 01727 constructor as of course constructors cannot return results! 01728 SeeAlso: DirPath::IsValid(const String_256& path); 01729 Errors: If it fails then it will call set error with the error found. 01730 01731 **********************************************************************************************/ 01732 01733 BOOL DirPath::IsValid() const 01734 { 01735 return PathName::IsValid(); 01736 } 01737 01738 /********************************************************************************************** 01739 01740 > virtual BOOL DirPath::IsValidAndReturnInfo(const String_256& ConstPath, String_256& tempFilename, 01741 String_256& tempLocation, String_256& tempFiletype, String_256& tempDrivename, 01742 BOOL SetErrors = TRUE) const 01743 01744 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 01745 Created: 6/2/96 01746 01747 Inputs: ConstPath - String representing the pathname to check 01748 SetErrors - Flag to say whether we should set errors or not (defaults to TRUE) 01749 01750 Outputs: tempFilename - String representing the filename (last entry in the path list) 01751 tempLocation - String representing the location (all entries before the last) 01752 tempFiletype - String representing the filetype (probably empty with dir names) 01753 tempDrivename - String representing the drive name 01754 01755 Returns: TRUE if the dirpath is parsed successfully or FALSE otherwise 01756 01757 Purpose: Parses a string representing a directory path and returns if it's valid or not. It 01758 also splits the string up into drivename, location and last directory name in the 01759 list. (it does this because it's overriding the pathname version, and can be 01760 useful if you know what it's doing !) 01761 01762 Routine called by IsValid to actually go and do the work involved with 01763 checking the pathname. Done this way so that internal calls do not have to 01764 parse the data again to get at the variables. 01765 01766 Errors: If it fails then it will call set error with the error found. 01767 This can now be supressed if required. 01768 01769 **********************************************************************************************/ 01770 01771 BOOL DirPath::IsValidAndReturnInfo(const String_256& ConstPath, String_256& tempFilename, 01772 String_256& tempLocation, String_256& tempFiletype, String_256& tempDrivename, BOOL SetErrors) const 01773 { 01774 // This routine doesn't actually do very much because it was found that the pathname class 01775 // returns ok for "C:\"... Possibly the FilePath class should detect this and return FALSE ? 01776 01777 return PathName::IsValidAndReturnInfo(ConstPath, tempFilename, tempLocation, tempFiletype, 01778 tempDrivename, SetErrors); 01779 } 01780 01781 01782 01783 01784 /********************************************************************************************** 01785 01786 > FilePath::FilePath() 01787 FilePath::FilePath(const FilePath& newPath) 01788 FilePath::FilePath(const String_256& path) 01789 01790 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 01791 Created: 6/2/96 01792 Purpose: FilePath class constructors 01793 01794 **********************************************************************************************/ 01795 01796 FilePath::FilePath() : PathName() 01797 { 01798 } 01799 FilePath::FilePath(const FilePath& newPath) : PathName(newPath) 01800 { 01801 } 01802 FilePath::FilePath(const String_256& path) : PathName(path) 01803 { 01804 } 01805 01806 /********************************************************************************************** 01807 01808 > BOOL DirPath::SetFilePath(const String_256& path) 01809 01810 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 01811 Created: 6/2/96 01812 Inputs: path - String representing a file + its pathname 01813 Returns: TRUE if the file pathname is parsed successfully or FALSE otherwise 01814 Purpose: Parses a string representing a path and sets up the class 01815 variables filetype, filename and location if the path is valid 01816 otherwise it sets them to null strings. 01817 Errors: None 01818 01819 **********************************************************************************************/ 01820 01821 BOOL FilePath::SetFilePath(const String_256& path) 01822 { 01823 return PathName::SetPathName(path); 01824 } 01825 01826 /********************************************************************************************** 01827 01828 > virtual BOOL FilePath::IsValid(const String_256& path) const 01829 01830 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 01831 Created: 6/2/96 01832 Inputs: path - String representing a pathname 01833 Returns: TRUE if the file pathname is parsed successfully or FALSE otherwise 01834 Purpose: Parses a string representing a file path and sets up the class 01835 variables filetype, filename and location if the path is valid. 01836 Cannot do the usual 8.3 checking of things like filenames as this is no longer 01837 valid given Chicago and NT non-FAT filing systems. 01838 Errors: If it fails then it will call set error with the error found. 01839 01840 **********************************************************************************************/ 01841 01842 BOOL FilePath::IsValid(const String_256& path) const 01843 { 01844 return PathName::IsValid(path); 01845 } 01846 01847 /********************************************************************************************** 01848 01849 > virtual BOOL FilePath::IsValid() const 01850 01851 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 01852 Created: 6/2/96 01853 Returns: TRUE if the present pathname has been parsed successfully or FALSE otherwise 01854 Purpose: Says whether the pathname currently in the class has been parsed correctly. 01855 This should only be used if the non-blank contructors have been called and more 01856 specifically the contructor which takes a pathname as a parameter has been used. 01857 This function then returns the result of the validation that happens in the 01858 constructor as of course constructors cannot return results! 01859 SeeAlso: FilePath::IsValid(const String_256& path); 01860 Errors: If it fails then it will call set error with the error found. 01861 01862 **********************************************************************************************/ 01863 01864 BOOL FilePath::IsValid() const 01865 { 01866 return PathName::IsValid(); 01867 } 01868 01869 /********************************************************************************************** 01870 01871 > virtual BOOL FilePath::IsValidAndReturnInfo(const String_256& ConstPath, String_256& tempFilename, 01872 String_256& tempLocation, String_256& tempFiletype, String_256& tempDrivename, BOOL SetErrors = TRUE) const 01873 01874 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 01875 Created: 6/2/96 01876 01877 Inputs: ConstPath - String representing the pathname to check 01878 SetErrors - Flag to say whether we should set errors or not (defaults to TRUE) 01879 01880 Outputs: tempFilename - String representing the filename 01881 tempLocation - String representing the location 01882 tempFiletype - String representing the filetype 01883 tempDrivename - String representing the drive name 01884 01885 Returns: TRUE if the pathname is parsed successfully or FALSE otherwise 01886 Purpose: Parses a string representing a path and returns the filetype, filename 01887 and location to the caller if the path is valid. 01888 Cannot do the usual 8.3 checking of things like filenames as this is no longer 01889 valid given Chicago and NT non-FAT filing systems. 01890 Routine called by IsValid to actually go and do the work involved with 01891 checking the pathname. Done this way so that internal calls do not have to 01892 parse the data again to get at the variables. 01893 Errors: If it fails then it will call set error with the error found. 01894 This can now be supressed if required. 01895 01896 **********************************************************************************************/ 01897 01898 BOOL FilePath::IsValidAndReturnInfo(const String_256& ConstPath, String_256& tempFilename, 01899 String_256& tempLocation, String_256& tempFiletype, String_256& tempDrivename, BOOL SetErrors) const 01900 { 01901 return PathName::IsValidAndReturnInfo(ConstPath, tempFilename, tempLocation, tempFiletype, 01902 tempDrivename, SetErrors); 01903 }