📄 filename.cpp
字号:
//####COPYRIGHTBEGIN####// // ----------------------------------------------------------------------------// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.//// This program is part of the eCos host tools.//// This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version.// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details.// // You should have received a copy of the GNU General Public License along with// this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// ----------------------------------------------------------------------------// //####COPYRIGHTEND#####include "stdafx.h"#include "FileName.h"#include <shlwapi.h>const TCHAR CFileName::cSep=_TCHAR('\\');CFileName::CFileName(LPCTSTR psz1,LPCTSTR psz2):CString(psz1){ Normalize(); operator+=(psz2);}CFileName::CFileName(LPCTSTR psz1,LPCTSTR psz2,LPCTSTR psz3):CString(psz1){ Normalize(); operator+=(psz2); operator+=(psz3);}CFileName::CFileName(LPCTSTR psz1,LPCTSTR psz2,LPCTSTR psz3,LPCTSTR psz4):CString(psz1){ Normalize(); operator+=(psz2); operator+=(psz3); operator+=(psz4);}CFileName::CFileName(LPCTSTR psz1,LPCTSTR psz2,LPCTSTR psz3,LPCTSTR psz4,LPCTSTR psz5):CString(psz1){ operator+=(psz2); operator+=(psz3); operator+=(psz4); operator+=(psz5);}CFileName AFXAPI operator+(const CFileName& string1, const CFileName& string2){ CFileName s; s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, string2.GetData()->nDataLength, string2.m_pchData); return s;}CFileName AFXAPI operator+(const CFileName& string, LPCTSTR lpsz){ ASSERT(lpsz == NULL || AfxIsValidString(lpsz)); CFileName s; s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData, CFileName::SafeStrlen(lpsz), lpsz); return s;}CFileName AFXAPI operator+(LPCTSTR lpsz, const CFileName& string){ ASSERT(lpsz == NULL || AfxIsValidString(lpsz)); CFileName s; s.ConcatCopy(CFileName::SafeStrlen(lpsz), lpsz, string.GetData()->nDataLength, string.m_pchData); return s;}CFileName AFXAPI operator+(const CFileName& string1, TCHAR ch){ CFileName s; s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, 1, &ch); return s;}CFileName AFXAPI operator+(TCHAR ch, const CFileName& string){ CFileName s; s.ConcatCopy(1, &ch, string.GetData()->nDataLength, string.m_pchData); return s;}const CFileName& CFileName::operator+=(LPCTSTR lpsz){ ASSERT(lpsz == NULL || AfxIsValidString(lpsz)); ConcatInPlace(SafeStrlen(lpsz), lpsz); return *this;}const CFileName& CFileName::operator+=(TCHAR ch){ ConcatInPlace(1, &ch); return *this;}const CFileName& CFileName::operator+=(const CFileName& string){ ConcatInPlace(string.GetData()->nDataLength, string.m_pchData); return *this;}void CFileName::ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData){ if(nSrcLen>0){ if(GetLength()>0){ // Appending a single separator to a non-null string is a no-op if(1==nSrcLen && cSep==*lpszSrcData){ return; } // Count the intervening separators int n=(cSep==m_pchData[GetLength()-1])+(cSep==*lpszSrcData); switch(n){ case 0: CString::ConcatInPlace(1, &cSep); break; case 1: break; case 2: lpszSrcData++; nSrcLen--; break; } } CString::ConcatInPlace(nSrcLen, lpszSrcData); }}void CFileName::ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data, int nSrc2Len, LPCTSTR lpszSrc2Data){ int n=1; int nNewLen = nSrc1Len + nSrc2Len; if(nSrc1Len>0){ if(1==nSrc2Len && cSep==*lpszSrc2Data){ // Appending a single separator to a non-null string is a no-op lpszSrc2Data++; nSrc2Len--; nNewLen--; } else { // Count the intervening separators n=(cSep==lpszSrc1Data[nSrc1Len-1])+(cSep==*lpszSrc2Data); switch(n){ case 0: nNewLen++; break; case 1: break; case 2: lpszSrc2Data++; nSrc2Len--; nNewLen--; break; } } } if (nNewLen != 0) { AllocBuffer(nNewLen); memcpy(m_pchData, lpszSrc1Data, nSrc1Len*sizeof(TCHAR)); LPTSTR p=m_pchData+nSrc1Len; if(0==n){ *p++=cSep; } memcpy(p, lpszSrc2Data, nSrc2Len*sizeof(TCHAR)); }}void CFileName::Normalize(){ // Remove any trailing slash int &n=GetData()->nDataLength; if(n>1 && (cSep==m_pchData[n-1])){ n--; m_pchData[n] = _TCHAR('\0'); }}const CFileName CFileName::FullName() const{ PTCHAR pFile; DWORD dwSize=::GetFullPathName (*this, 0, NULL, &pFile); if(dwSize>0){ CString strCopy; ::GetFullPathName (*this, 1+dwSize, strCopy.GetBuffer(1+dwSize), &pFile); strCopy.ReleaseBuffer(); return strCopy; } else { return *this; }}const CFileName CFileName::ShortName() const{ DWORD dwSize=::GetShortPathName (*this, NULL, 0); if(dwSize>0){ CString strCopy; ::GetShortPathName (*this, strCopy.GetBuffer(1+dwSize), 1+dwSize); strCopy.ReleaseBuffer(); return strCopy; } else { return *this; }}const CFileName CFileName::NoSpaceName() const// sans spaces{ CStringArray ar1,ar2; const CString str2(ShortName()); LPCTSTR pc,pcStart; pcStart=*this; for(pc=*this;*pc;pc++){ if(_TCHAR('\\')==*pc){ ar1.Add(CString(pcStart,pc-pcStart)); pcStart=pc; } } ar1.Add(CString(pcStart,pc-pcStart)); pcStart=str2; for(pc=str2;*pc;pc++){ if(_TCHAR('\\')==*pc){ ar2.Add(CString(pcStart,pc-pcStart)); pcStart=pc; } } ar2.Add(CString(pcStart,pc-pcStart)); ASSERT(ar1.GetSize()==ar2.GetSize()); CString rc; for(int i=0;i<ar1.GetSize();i++){ rc+=(-1==ar1[i].Find(_TCHAR(' ')))?ar1[i]:ar2[i]; } return rc;}//const CFileName CFileName::Tail() const{ TCHAR *ch=_tcsrchr(m_pchData,cSep); return ch?ch+1:m_pchData;}const CFileName CFileName::Head() const{ TCHAR *ch=_tcsrchr(m_pchData,cSep); return ch?CFileName(m_pchData,ch-m_pchData):m_pchData;}// GetFileAttributes is not available in Win95 so we test the water firstFILETIME CFileName::LastModificationTime() const{ static HINSTANCE hInst=LoadLibrary(_T("kernel32.dll")); ASSERT(hInst); #ifdef _UNICODE#define GETFILEATTRIBUTESNAME "GetFileAttributesExW"#else#define GETFILEATTRIBUTESNAME "GetFileAttributesExA"#endif // !UNICODE typedef BOOL (WINAPI *GetFileAttributesP)(LPCTSTR,GET_FILEEX_INFO_LEVELS,LPVOID); static GetFileAttributesP p=(GetFileAttributesP)GetProcAddress(hInst,GETFILEATTRIBUTESNAME); if(p){ WIN32_FILE_ATTRIBUTE_DATA data; if((*p)(*this, GetFileExInfoStandard, (LPVOID)&data)){ return data.ftLastWriteTime; } } else { HANDLE h=CreateFile(*this,0,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); FILETIME ft; if(INVALID_HANDLE_VALUE!=h){ BOOL b=::GetFileTime(h,NULL,NULL,&ft); ::CloseHandle(h); if(b){ return ft; } } } static FILETIME ftNull={0,0}; return ftNull;}bool CFileName::SetFileAttributes(DWORD dwFileAttributes) const{ return ::SetFileAttributes (*this, dwFileAttributes)!=0;}bool CFileName::SameFile(const CFileName &o) const{ return 0==ShortName().CompareNoCase(o.ShortName());}CFileName CFileName::ExpandEnvironmentStrings(LPCTSTR psz){ // First call simply determines the size CFileName f; DWORD dwSize=::ExpandEnvironmentStrings(psz, NULL, 0); if(dwSize>0){ ::ExpandEnvironmentStrings(psz, f.GetBuffer(dwSize), dwSize); f.ReleaseBuffer(); } else { f=psz; } return f;}const CFileName& CFileName::ExpandEnvironmentStrings(){ *this=CFileName::ExpandEnvironmentStrings(*this); return *this;}// Helper for Relative() psz is in full format.CFileName CFileName::Drive(LPCTSTR psz){ if(_istalpha(psz[0])){ return psz[0]; } else if(cSep==psz[0]&&cSep==psz[1]){ TCHAR *c=_tcschr(psz+2,cSep); if(c){ c=_tcschr(c+1,cSep); if(c){ return CString(psz,c-psz); } } } return _T("");}CFileName CFileName::Relative(LPCTSTR compare,LPCTSTR current){ CString rc; bool b=(TRUE==PathRelativePathTo(rc.GetBuffer(1+MAX_PATH),current,FILE_ATTRIBUTE_DIRECTORY,compare,0)); rc.ReleaseBuffer(); //TRACE(_T("compare=%s current=%s result=%s (b=%d)\n"),compare,current,b?rc:compare,b); return b?rc:compare;} const CFileName& CFileName::MakeRelative(LPCTSTR pszRelativeTo){ *this=CFileName::Relative(*this,pszRelativeTo); return *this;}CFileName CFileName::GetCurrentDirectory(){ CFileName f; ::GetCurrentDirectory(1+_MAX_PATH,f.GetBuffer(1+_MAX_PATH)); f.ReleaseBuffer(); f.Normalize(); return f;}const CFileName& CFileName::Append(LPCTSTR lpsz){ ASSERT(lpsz == NULL || AfxIsValidString(lpsz)); CString::ConcatInPlace(SafeStrlen(lpsz), lpsz); return *this; }const CFileName& CFileName::Append(TCHAR ch){ ConcatInPlace(1, &ch); return *this;}bool CFileName::IsAbsolute() const{ int nLength=GetLength(); LPCTSTR psz=*this; return (nLength>0 && (cSep==psz[0]))|| // starts with '\' (nLength>1 && ( (_istalpha(psz[0]) && _TCHAR(':')==psz[1]) || // starts with [e.g.] "c:\" (cSep==psz[0] && cSep==psz[1]))); // UNC}// Return an array of filename pieces. Plugs '\0's into 'this', which// is therefore subsequently only usable as referenced by the returned array.LPCTSTR *CFileName::Chop(){ TCHAR *c; // Count the separators int nSeps=0; for(c=_tcschr(m_pchData,cSep);c;c=_tcschr(c+1,cSep)){ nSeps++; } LPCTSTR *ar=new LPCTSTR[2+nSeps]; // +1 for first, +1 for terminating 0 ar[0]=m_pchData; int i=1; for(c=_tcschr(m_pchData,cSep);c;c=_tcschr(c+1,cSep)){ ar[i++]=c+1; *c=_TCHAR('\0'); } ar[i]=0; return ar;}CFileName CFileName::GetTempPath(){ CFileName f; ::GetTempPath(1+_MAX_PATH,f.GetBuffer(1+_MAX_PATH)); f.ReleaseBuffer(); f.Normalize(); return f; }const CFileName CFileName::CygPath () const { TCHAR buf[2+MAX_PATH]; LPCTSTR rc=buf+1; if(!GetShortPathName(m_pchData,1+buf,MAX_PATH)){ _tcscpy(1+buf,m_pchData); } if(_istalpha(*rc)&&_TCHAR(':')==rc[1]){ // Convert c:\ to //c/ [this is the bit that requires the first char of buf] buf[0]=_TCHAR('/'); buf[2]=buf[1]; buf[1]=_TCHAR('/'); rc=buf; } for(TCHAR *c=buf+1;*c;c++){ if(_TCHAR('\\')==*c){ *c=_TCHAR('/'); } } return rc;}bool CFileName::CreateDirectory(bool bParentsToo,bool bFailIfAlreadyExists) const{ LPCTSTR pszDir=m_pchData; if(bParentsToo){ // Create intermediate directories for(LPCTSTR c=_tcschr(pszDir,_TCHAR('\\'));c;c=_tcschr(c+1,_TCHAR('\\'))){ if(c==pszDir+2 && _istalpha(pszDir[0]) && _TCHAR(':')==pszDir[1]){ continue; // don't attempt to create "C:" } const CFileName strDir(pszDir,c-pszDir); if(!(strDir.IsDir()? (!bFailIfAlreadyExists) : ::CreateDirectory(strDir,NULL))){ return false; } } } return IsDir()? (!bFailIfAlreadyExists) : (TRUE==::CreateDirectory(pszDir,NULL));}const CString CFileName::Extension() const{ LPCTSTR ch=_tcsrchr(m_pchData,_TCHAR('.')); if(ch && !_tcschr(ch,cSep)){ return CString(ch+1); } else { return _T(""); }}const CString CFileName::Root() const{ LPCTSTR ch=_tcsrchr(m_pchData,_TCHAR('.')); if(ch && !_tcschr(ch,cSep)){ return CString(m_pchData,ch-m_pchData); } else { return m_pchData; }}CFileName CFileName::SetCurrentDirectory(LPCTSTR pszDir){ const CFileName strPwd=GetCurrentDirectory(); return ::SetCurrentDirectory(pszDir)?strPwd:_T("");}bool CFileName::RecursivelyDelete(){ CFileNameArray ar; for(int i=FindFiles(*this,ar)-1;i>=0;--i){ ::DeleteFile(ar[i]); } for(i=FindFiles(*this,ar,_T("*.*"),true,0)-1;i>=0;--i){ ::RemoveDirectory(ar[i]); } return TRUE==::RemoveDirectory(*this);}int CFileName::FindFiles (LPCTSTR pszDir,CFileNameArray &ar,LPCTSTR pszPattern/*=_T("*.*")*/,bool bRecurse/*=true*/,DWORD dwExclude/*=FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN*/){ ar.RemoveAll(); CFileFind finder; BOOL bMore=finder.FindFile(CFileName(pszDir)+pszPattern); while (bMore) { bMore = finder.FindNextFile(); if(!finder.IsDots() && !finder.MatchesMask(dwExclude)){ CFileName strFile(finder.GetFilePath()); ar.Add(strFile); } } if(bRecurse){ CFileFind finder; BOOL bMore=finder.FindFile(CFileName(pszDir)+_T("*.*")); while (bMore) { bMore = finder.FindNextFile(); if(!finder.IsDots() && finder.IsDirectory()){ CFileNameArray ar2; FindFiles(finder.GetFilePath(),ar2,pszPattern,bRecurse,dwExclude); ar.Append(ar2); } } } return ar.GetSize();}void CFileName::ReplaceExtension(LPCTSTR pszNewExt){ ASSERT(pszNewExt); if(_TCHAR('.')==*pszNewExt){ // Be tolerant of whether '.' is included in what we are passed: pszNewExt++; } LPTSTR pch=GetBuffer(2+GetLength()+_tcslen(pszNewExt)); LPTSTR pcExt=_tcsrchr(pch,_TCHAR('.')); if(NULL==pcExt || _tcschr(pcExt,cSep)){ // No existing extension pcExt=pch+GetLength(); *pcExt++=_TCHAR('.'); } _tcscpy(pcExt+1,pszNewExt); ReleaseBuffer();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -