00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <fs/sys/fsFileDir.h>
00015
00016 #if defined(UNDER_CE)
00017 # include <fs/ut/fsStrUt.h>
00018 #endif
00019
00020
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
00052
00053 #include <vector>
00054 #include <string>
00055
00056 #if defined(_WIN32)
00057 # include <windows.h>
00058 #endif
00059
00060
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
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
00198
00199 std::string str = std::string(pszDir) + std::string(GetPathSpr());
00200
00201 if(pszFile)
00202 str.append(pszFile);
00203
00204
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
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
00234
00235 namespace {
00236
00237
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
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
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
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 }
00391
00392
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