fs/sys/fsFileDir.cpp

Go to the documentation of this file.
00001 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
00002 /*                          _______      ______    ______          __      */
00003 /*  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~    / ____(_)___ / ___ /)  / ____/___  ____/ /__    */
00004 /*     [fsFileDir]        / /_  / / __ \\__ \|/  / /   / __ \/ __  / _ \   */
00005 /*       rev. 8          / __/ / / /_/ /__/ /   / /___/ /_/ / /_/ /  __/   */
00006 /*    15th Jan 2007     /_/   /_/ ,___/____/    \____/\____/\__,_/\___/    */
00007 /*     [x] stable              /_/ (c) 2004-07 Filip STOKLAS (FipS)        */
00008 /*  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~       http://HOLE.4FipS.com/fips_code.php          */
00009 /*                                                                         */
00010 /* This code is free for personal and commercial use. You may redistribute */
00011 /* it by any means. If you use the code for your own projects please give  */
00012 /* me credit. Please send a bug report. Don't alter or remove this header! */
00013 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
00014 #include <fs/sys/fsFileDir.h>
00015 
00016 #if defined(UNDER_CE)
00017 #   include <fs/ut/fsStrUt.h> // wide-character string helpers
00018 #endif
00019 
00020 // >>> COMMON SUPPORT BLOCK (rev. 6)
00021 #if defined(FS_HAS_FSASSERT)
00022 #   include <fs/sys/fsAssert.h>
00023 #else
00024 #   include <cassert>
00025 #   if !defined(FS_ASSERT)
00026 #       define FS_ASSERT(exp) assert(exp)
00027 #   endif
00028 #   if !defined(FS_ASSERT_MSG)
00029 #       define FS_ASSERT_MSG(exp, msg) assert(exp && msg)
00030 #   endif
00031 #   if !defined(FS_VERIFY)
00032 #       define FS_VERIFY(exp) \
00033         { bool bExp = !!(exp); assert(bExp && #exp); bExp; }
00034 #   endif
00035 #   if !defined(FS_VERIFY_MSG)
00036 #       define FS_VERIFY_MSG(exp, msg) \
00037         { bool bExp = !!(exp); assert(bExp && #exp && msg); bExp; }
00038 #   endif
00039 #   if !defined(FS_STATIC_ASSERT)
00040 #       define FS_STATIC_ASSERT(exp) { char error[(exp) ? 1 : 0]; error; }
00041 #   endif
00042 #endif
00043 #if !defined(FS_VERIFY_RETURN)
00044 #   define FS_VERIFY_RETURN(exp) \
00045     if(!(exp)) { FS_ASSERT_MSG(0, #exp "<return>"); return; }
00046 #endif
00047 #if !defined(FS_VERIFY_RETURN_VAL)
00048 #   define FS_VERIFY_RETURN_VAL(exp, ret) \
00049     if(!(exp)) { FS_ASSERT_MSG(0, #exp "<returns:>" #ret); return (ret); }
00050 #endif
00051 // <<< COMMON SUPPORT BLOCK (rev. 6)
00052 
00053 #include <vector>
00054 #include <string>
00055 
00056 #if defined(_WIN32)
00057 #   include <windows.h>
00058 #endif
00059 
00060 // provide detailed memory tracking information
00061 #if defined(FS_HAS_FSMEMMGR)
00062 #   include <fs/sys/fsMemMgr.h>
00063 #endif
00064 //---------------------------------------------------------------------------
00065 #if (_MSC_VER >= 1400) // MSVC8
00066 #   pragma warning(disable : 4996) // function was marked as deprecated
00067 #endif
00068 //---------------------------------------------------------------------------
00069 using namespace fs::sys::fdr;
00070 //---------------------------------------------------------------------------
00071 //--- FUNCTIONS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00072 //---------------------------------------------------------------------------
00073 const char * fs::sys::fdr::GetPathSpr()
00074 {
00075 #if defined(_WIN32)
00076 
00077     static char szSpr[] = "\\";
00078     return szSpr;
00079     
00080 #else
00081 #   error Unknown platform!
00082 #endif
00083 }
00084 //---------------------------------------------------------------------------
00085 const char * fs::sys::fdr::GetNewLn()
00086 {
00087     static char szNewLn[] = "\n";
00088     return szNewLn;
00089 }
00090 //---------------------------------------------------------------------------
00092 const char * fs::sys::fdr::GetAppDir()
00093 {
00094 #if defined(UNDER_CE)
00095 
00096     static wchar_t wszTemp[MAX_PATH + 1];
00097     ::GetModuleFileName(0, wszTemp, MAX_PATH);
00098     
00099     static char szTemp[MAX_PATH + 1];
00100     fs::ut::str::WStr2Str(wszTemp, szTemp);
00101     
00102     char *pszSprPos = ::strrchr(szTemp, GetPathSpr()[0]);
00103     FS_ASSERT(pszSprPos);
00104     *(pszSprPos + 1) = '\0';
00105     
00106     return szTemp;
00107 
00108 #elif defined(_WIN32)
00109     
00110     static char szTemp[MAX_PATH + 1];
00111     ::GetCurrentDirectoryA(MAX_PATH, szTemp);
00112     
00113     ::strcat(szTemp, GetPathSpr());
00114     
00115     return szTemp;
00116 
00117 #else
00118 #   error Unknown platform!
00119 #endif
00120 }
00121 //---------------------------------------------------------------------------
00122 bool fs::sys::fdr::IsDirExist(const char *pszFullDir)
00123 {
00124     FS_VERIFY_RETURN_VAL(pszFullDir, false);
00125     
00126 #if defined(UNDER_CE)
00127 
00128     using namespace fs::ut::str;
00129     DWORD Attr = ::GetFileAttributes(WStrHldr_t(pszFullDir).GetWStr());
00130     
00131     return Attr != 0xFFFFFFFF && (Attr | FILE_ATTRIBUTE_DIRECTORY);
00132 
00133 #elif defined(_WIN32)
00134 
00135     DWORD Attr = ::GetFileAttributesA(pszFullDir);
00136     
00137     return Attr != INVALID_FILE_ATTRIBUTES && (Attr |
00138      FILE_ATTRIBUTE_DIRECTORY);
00139 
00140 #else
00141 #   error Unknown platform!
00142 #endif
00143 }
00144 //---------------------------------------------------------------------------
00150 bool fs::sys::fdr::MakeDir(const char *pszFullDir)
00151 {
00152     FS_VERIFY_RETURN_VAL(pszFullDir, false);
00153     
00154 #if defined(UNDER_CE)
00155 
00156     FS_ASSERT_MSG(0, "Not implemented!");
00157     return false;
00158 
00159 #elif defined(_WIN32)
00160 
00161     const char chSpr = GetPathSpr()[0];
00162     const char *pSpr = ::strchr(pszFullDir, chSpr);
00163     FS_ASSERT(pSpr);
00164     
00165     do
00166     {
00167         std::string strSub(pszFullDir, 0, pSpr - pszFullDir + 1);
00168                 
00169         if(!IsDirExist(strSub.c_str()))
00170             if(!::CreateDirectoryA(strSub.c_str(), 0))
00171                 return false;
00172             
00173         pSpr = ::strchr(pSpr + 1, chSpr);
00174     }
00175     while(pSpr);
00176     
00177     return true;
00178 
00179 #else
00180 #   error Unknown platform!
00181 #endif
00182 }
00183 //---------------------------------------------------------------------------
00192 void fs::sys::fdr::NicePath(char *pszOut, const char *pszDir, const char
00193  *pszFile)
00194 {
00195     FS_VERIFY_RETURN(pszOut && pszDir);
00196 
00197     // form the directory part
00198     
00199     std::string str = std::string(pszDir) + std::string(GetPathSpr());
00200     
00201     if(pszFile) // the file part is optional
00202         str.append(pszFile);
00203         
00204     // remove multiple path separators and swap '/' <=> '\'
00205     
00206     const char chSpr = GetPathSpr()[0];
00207     const char chBadSpr = chSpr == '/' ? '\\' : '/';
00208     
00209     std::string::iterator it = str.begin();
00210     char chOld = '\0';
00211     
00212     while(it != str.end())
00213     {
00214         char &ch = *it;
00215     
00216         if(ch == chBadSpr) // '/' <=> '\'
00217             ch = chSpr;
00218             
00219         // eliminate multiple path separators
00220         if(ch == chSpr && chOld == chSpr)
00221         {
00222             str.erase(it);
00223             continue;
00224         }
00225 
00226         chOld = ch;
00227         it++;
00228     }
00229     
00230     ::strcpy(pszOut, str.c_str());
00231 }
00232 //---------------------------------------------------------------------------
00233 //--- ANONYMOUS NAMESPACE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00234 //---------------------------------------------------------------------------
00235 namespace {
00236 //---------------------------------------------------------------------------
00237 //--- CLASS DirLstImpl_t >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00238 //---------------------------------------------------------------------------
00239 class DirLstImpl_t
00240 {
00241 public:
00242 
00243     explicit DirLstImpl_t(const char *pszFullDir, bool bRecur = false,
00244      bool bInclDirs = false, bool bInclFiles = true);
00245     bool IsValid() const;
00246 
00247     const char * GetRoot() const;
00248     int GetNum() const;
00249     const char * GetAt(int nIndex) const;
00250 
00251 private:
00252 
00253     DirLstImpl_t();
00254     DirLstImpl_t(const DirLstImpl_t &);
00255     DirLstImpl_t & operator = (const DirLstImpl_t &);
00256     
00257     //---
00258     
00259     std::string m_strRoot;
00260     std::vector<std::string> m_Items;
00261 };
00262 //---------------------------------------------------------------------------
00263 DirLstImpl_t::DirLstImpl_t(const char *pszFullDir, bool bRecur,
00264  bool bInclDirs, bool bInclFiles):
00265 m_strRoot(pszFullDir ? pszFullDir : "")
00266 {
00267     FS_VERIFY_RETURN(pszFullDir);
00268 
00269 #if defined(_WIN32)
00270 
00271     const char * const pSpr = fs::sys::fdr::GetPathSpr();
00272 
00273     //--- LIST DIRECTORIES ---
00274     
00275     if(bRecur)
00276     {
00277         std::string strRoot = pszFullDir;
00278                         
00279         int nPos = -1;
00280         while(nPos < static_cast<int>(m_Items.size()))
00281         {
00282             if(nPos >= 0)
00283                 strRoot = std::string(pszFullDir) + m_Items[nPos];
00284                 
00285             strRoot.append("*.*");
00286             
00287             WIN32_FIND_DATAA FindData;
00288             HANDLE hFile = ::FindFirstFileA(strRoot.c_str(), &FindData);
00289             bool bDone = hFile == INVALID_HANDLE_VALUE;
00290         
00291             while(!bDone)
00292             {
00293                 if(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY &&
00294                  ::strcmp(FindData.cFileName, ".") != 0 &&
00295                  ::strcmp(FindData.cFileName, "..") != 0
00296                 )
00297                 {
00298                     m_Items.push_back(
00299                      std::string(nPos >= 0 ? m_Items[nPos] : "").
00300                      append(FindData.cFileName).append(pSpr)
00301                     );
00302                 }
00303                 
00304                 bDone = ::FindNextFileA(hFile, &FindData) ? false : true;
00305             }
00306             
00307             ::FindClose(hFile);
00308             ++nPos;
00309         }
00310     }
00311     
00312     const int nDirCount = static_cast<int>(m_Items.size());
00313         
00314     //--- LIST FILES ---
00315     
00316     if(bInclFiles)
00317     {
00318         std::string strRoot = pszFullDir;
00319         
00320         int nPos = -1;
00321                 
00322         while(nPos < nDirCount)
00323         {
00324             if(nPos >= 0)
00325                 strRoot = std::string(pszFullDir) + m_Items[nPos];
00326                 
00327             strRoot.append("*.*");
00328             
00329             WIN32_FIND_DATAA FindData;
00330             HANDLE hFile = ::FindFirstFileA(strRoot.c_str(), &FindData);
00331             bool bDone = hFile == INVALID_HANDLE_VALUE;
00332         
00333             while(!bDone)
00334             {
00335                 if(!(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
00336                 {
00337                     m_Items.push_back(
00338                      std::string(nPos >= 0 ? m_Items[nPos] : "").
00339                      append(FindData.cFileName)
00340                     );
00341                 }
00342                 
00343                 bDone = ::FindNextFileA(hFile, &FindData) ? false : true;
00344             }
00345             
00346             ::FindClose(hFile);
00347             ++nPos;
00348         }
00349     }
00350     
00351     //--- REMOVE UNNECESSARY DIRECTORIES ---    
00352     
00353     if(!bInclDirs)
00354         m_Items.erase(m_Items.begin(), m_Items.begin() + nDirCount);
00355         
00356     //---
00357             
00358 #else
00359 #   error Unknown platform!
00360 #endif
00361 }
00362 //---------------------------------------------------------------------------
00363 bool DirLstImpl_t::IsValid() const
00364 {
00365     return !m_strRoot.empty();
00366 }
00367 //---------------------------------------------------------------------------
00368 const char * DirLstImpl_t::GetRoot() const
00369 {
00370     FS_VERIFY_RETURN_VAL(IsValid(), 0);
00371 
00372     return m_strRoot.c_str();
00373 }
00374 //---------------------------------------------------------------------------
00375 int DirLstImpl_t::GetNum() const
00376 {
00377     FS_VERIFY_RETURN_VAL(IsValid(), 0);
00378 
00379     return static_cast<int>(m_Items.size());
00380 }
00381 //---------------------------------------------------------------------------
00382 const char * DirLstImpl_t::GetAt(int nIndex) const
00383 {
00384     FS_VERIFY_RETURN_VAL(IsValid(), 0);
00385     FS_VERIFY_RETURN_VAL(nIndex >= 0 && nIndex < GetNum(), 0);
00386     
00387     return m_Items[nIndex].c_str();
00388 }
00389 //---------------------------------------------------------------------------
00390 } // anonymous namespace
00391 //---------------------------------------------------------------------------
00392 //--- CLASS DirLst_t >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00393 //---------------------------------------------------------------------------
00403 DirLst_t::DirLst_t(const char *pszFullDir, bool bRecur, bool bInclDirs,
00404  bool bInclFiles):
00405 m_pImpl(new DirLstImpl_t(pszFullDir, bRecur, bInclDirs, bInclFiles))
00406 {
00407     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00408 }
00409 //---------------------------------------------------------------------------
00410 DirLst_t::~DirLst_t()
00411 {
00412     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00413     delete static_cast<DirLstImpl_t *>(m_pImpl);
00414 }
00415 //---------------------------------------------------------------------------
00416 bool DirLst_t::IsValid() const
00417 {
00418     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00419     return static_cast<DirLstImpl_t *>(m_pImpl)->IsValid();
00420 }
00421 //---------------------------------------------------------------------------
00422 const char * DirLst_t::GetRoot() const
00423 {
00424     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00425     return static_cast<DirLstImpl_t *>(m_pImpl)->GetRoot();
00426 }
00427 //---------------------------------------------------------------------------
00428 int DirLst_t::GetNum() const
00429 {
00430     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00431     return static_cast<DirLstImpl_t *>(m_pImpl)->GetNum();
00432 }
00433 //---------------------------------------------------------------------------
00434 const char * DirLst_t::GetAt(int nIndex) const
00435 {
00436     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00437     return static_cast<DirLstImpl_t *>(m_pImpl)->GetAt(nIndex);
00438 }
00439 //---------------------------------------------------------------------------

FipS' Code (Thu Feb 15 22:43:35 2007) - (c) Filip STOKLAS (FipS) - [ www ] [ Guest Book ]