filepath.cpp
来自「这是VCF框架的代码」· C++ 代码 · 共 654 行 · 第 1/2 页
CPP
654 行
//FilePath.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*/#include "vcf/FoundationKit/FoundationKit.h"using namespace VCF;FilePath::FilePath(){}FilePath::FilePath( const String& filename ){ filename_ = transformToNative( filename );}FilePath::FilePath( const FilePath& filePath )//: Object(filePath){ filename_ = transformToNative( filePath.filename_ );}FilePath::~FilePath(){}String FilePath::getDriveSeparator(){#ifdef WIN32 return L":";#else return L"";#endif}bool FilePath::isRelativePath( const String& filename ){ bool result = false; String drive = getDriveName( filename ); VCFChar c = filename[0]; if ( ( c != '/' && c != '\\' ) && ( drive.empty() ) ) { result = true; } else if ( c == '.' ) { // is relative if ( "./" or "../" at the beginning ) int pos = filename.find_first_of( L"/\\" ); result = ( ( pos == 1 ) || ( ( pos == 2 ) && ( filename[0] == L'.' ) ) ); } return result;}bool FilePath::isDirectoryName( const String& path ){ VCFChar c = path[ path.size() - 1 ]; bool result = ( c == '/' || c == '\\' ); return result;}void FilePath::splitDrive( const String& fullname, String& drive, String& pathname ){ // DriveSeparator is included in drive size_t lastDrivePos = fullname.find_last_of( FilePath::getDriveSeparator() ); if ( String::npos != lastDrivePos ) { drive = fullname.substr( 0, lastDrivePos + 1 ); pathname = fullname.substr( lastDrivePos + 1, fullname.size() - lastDrivePos - 1 ); } else { drive.erase(); pathname = fullname; } VCF_ASSERT( fullname == drive + pathname ); }String FilePath::getDriveName( const String& fullname ){ // DriveSeparator is included in drive size_t lastDrivePos = fullname.find_last_of( FilePath::getDriveSeparator() ); if ( String::npos != lastDrivePos ) { return fullname.substr( 0, lastDrivePos + 1 ); } else { return String( L"" ); }}void FilePath::splitPath( const String& fullname, String& path, String& name ){ // DirectorySeparator is included in path /** * Remarks: * * The main reason why FilePath, looks for both '/' and '\\' under Windows in the * implementation of some of its member function, is that under Windows they are both used. * By not doing this we can have the surprising effect of having a different behaviour * of the code under a Window and a 'nix platform. * * A second reason is that this version works with both an OSSpecific and a Native formats, * with a negligible performance penalty. */ size_t lastDirsepPos = fullname.find_last_of( L"/\\" ); if ( lastDirsepPos != String::npos ) { path = fullname.substr( 0, lastDirsepPos + 1 ); name = fullname.substr( lastDirsepPos + 1, fullname.size() - lastDirsepPos - 1 ); } else { path.erase(); name = fullname; } VCF_ASSERT( fullname == path + name ); }String FilePath::getPathName( const String& fullname, const bool& includeDriveName ){ // DirectorySeparator is included in path size_t lastDrivePos = String::npos; if ( !includeDriveName ) { lastDrivePos = fullname.find_last_of( FilePath::getDriveSeparator() ); } size_t lastDirsepPos = fullname.find_last_of( L"/\\" ); String path; if ( lastDrivePos != String::npos ) { if ( lastDirsepPos != String::npos ) { path = fullname.substr( lastDrivePos + 1, lastDirsepPos - lastDrivePos ); } else { path = fullname.substr( lastDrivePos + 1, fullname.size() - lastDrivePos ); } } else { if ( lastDirsepPos != String::npos ) { path = fullname.substr( 0, lastDirsepPos + 1 ); } else { path.erase(); } } return path;}void FilePath::splitExtension( const String& fullname, String& root, String& ext ){ // ExtensionSeparator is included in ext size_t lastExtPos = fullname.find_last_of( FilePath::getExtensionSeparator() ); if ( lastExtPos != String::npos ) { root = fullname.substr( 0, lastExtPos ); ext = fullname.substr( lastExtPos, fullname.size() - lastExtPos ); } else { root = fullname; ext.erase(); } VCF_ASSERT( fullname == root + ext ); }String FilePath::getBaseName( const String& fullname, const bool& includeExtension ){ size_t lastDirsepPos = fullname.find_last_of( L"/\\" ); size_t lastExtPos = String::npos; if ( !includeExtension ) { lastExtPos = fullname.find_last_of( FilePath::getExtensionSeparator() ); } String path; if ( lastDirsepPos != String::npos ) { if ( lastExtPos != String::npos ) { path = fullname.substr( lastDirsepPos + 1, lastExtPos - lastDirsepPos - 1 ); } else { path = fullname.substr( lastDirsepPos + 1, fullname.size() - lastDirsepPos - 1 ); } } else { if ( lastExtPos != String::npos ) { path = fullname.substr( 0, lastExtPos ); } else { path = fullname; } } return path;}String FilePath::getExtension( const String& fullname ){ String path; size_t lastExtPos = fullname.find_last_of( FilePath::getExtensionSeparator() ); if ( lastExtPos != String::npos ) { path = fullname.substr( lastExtPos, fullname.size() - 1 ); } return path;}bool compareDirectoryComponent( const String& s1, const String& s2 ){ //returns true if s1 == s2 taking in consideration if the filesystem is case sensitive bool result = false;#ifdef WIN32 result = (StringUtils::lowerCase(s1) == StringUtils::lowerCase(s2));#else result = (s1 == s2);#endif return result;}String FilePath::getTransformedToRelativePathName( const String& fullPath, const String& workingPath ){ String result; String fullPathCopy, workDir; if ( workingPath.empty() ) { workDir = System::getCurrentWorkingDirectory(); } else { //make sure it's a dir name workDir = FilePath::getPathName( workingPath, true ); } if ( workDir.empty() ) { //ok we're screwed - throw an exception return L""; } workDir = FilePath::transformToNative( workDir ); fullPathCopy = FilePath::transformToNative( fullPath ); std::vector<String> workPathComponents = getPathComponents( workDir ); std::vector<String> currentPathComponents = getPathComponents( fullPathCopy ); String workingDrive = FilePath::getDriveName( workDir ); String currentDrive = FilePath::getDriveName( fullPathCopy ); if ( StringUtils::lowerCase(currentDrive) == StringUtils::lowerCase(workingDrive) ) { String sep = String( 1, (VCFChar)DirectorySeparator ); String tmp; std::vector<String>::iterator workIt = workPathComponents.begin(); size_t workingIndex = 0; size_t currentIndex = 0; while ( workIt != workPathComponents.end() ) { if ( (!compareDirectoryComponent( *workIt, currentPathComponents[currentIndex] )) || (workingIndex != currentIndex) ) { tmp += L".." + sep; } else { currentIndex ++; if ( currentIndex >= currentPathComponents.size() ) { currentIndex = currentPathComponents.size()-1; } } workingIndex ++; workIt ++; } if ( currentIndex > 0 ) { //this is because we are at the root / dir, don't //need the duplicate '/' character //test to see if we need to add a local dir if ( tmp.empty() ) { tmp += L"." + sep; } //only go on if we are NOT on the last element if ( currentIndex <= currentPathComponents.size()-1 ) { for ( size_t j=currentIndex; j<currentPathComponents.size(); j++ ) { if ( j < workPathComponents.size() ) { if ( !compareDirectoryComponent( workPathComponents[j], currentPathComponents[j]) ) { tmp += currentPathComponents[j]; } } else { tmp += currentPathComponents[j]; } } } } result = tmp + FilePath::getBaseName( fullPathCopy, true ); } else { result = fullPathCopy; } return result;}String FilePath::getExpandedRelativePathName( const String& fullPath, const String& workingPath ){ if ( !FilePath::isRelativePath( fullPath ) ) { return FilePath::transformToNative( fullPath ); } String result, workDir; String fullPathCopy = fullPath; if ( workingPath.empty() ) { workDir = System::getCurrentWorkingDirectory(); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?