Main Page Namespace List Class Hierarchy Compound List File List Namespace Members Compound Members File Members Related Pages

# DirWalker.cpp

Go to the documentation of this file.

    00001
    00040 #include <stdio.h>
    00041 #include <string.h>
    00042 #include "DirWalker.h"
    00043 #include "Debug.h"
    00044
    00045 #ifndef WIN32
    00046 #include <sys/stat.h>
    00047 #define FILE_SEP '/'
    00048 #else
    00049 #define FILE_SEP '\\'
    00050 #endif
    00051
    00052 // IMPORTANT: The code for WIN32 hasn't been tested and it's very likely
    00053 // that it still requires some modifications.
    00054
    00055 DirWalker::DirWalker()
    00056 {
    00057         hFile = INVALID_HANDLE_VALUE;
    00058         *szDirPath = '\0';
    00059         nDirPathLen = 0;
    00060 }
    00061
    00062 bool DirWalker::OpenDir(const char* szDirName)
    00063 {
    00064         CloseDir();
    00065
    00066 #ifdef WIN32
    00067         hFile = FindFirstFile(szDirName, &findData); // perhaps szDirName + "*.*"
    00068 #else
    00069         hFile = opendir(szDirName);
    00070 #endif
    00071
    00072         if (hFile != INVALID_HANDLE_VALUE)
    00073         {
    00074                 nDirPathLen = strlen(szDirName);
    00075                 memcpy(szDirPath, szDirName, nDirPathLen + 1);
    00076
    00077                 if (szDirPath[nDirPathLen - 1] != FILE_SEP)
    00078                 {
    00079                         szDirPath[nDirPathLen] = FILE_SEP;
    00080                         szDirPath[nDirPathLen + 1] = '\0';
    00081                         nDirPathLen++;
    00082                 }
    00083
    00084                 return true;
    00085         }
    00086
    00087         return false;
    00088 }
    00089
    00090 void DirWalker::CloseDir()
    00091 {
    00092         if (hFile != INVALID_HANDLE_VALUE)
    00093         {
    00094 #ifdef WIN32
    00095                 FindClose(hFile);
    00096 #else
    00097                 closedir(hFile);
    00098 #endif
    00099                 hFile = INVALID_HANDLE_VALUE;
    00100                 *szDirPath = '\0';
    00101                 nDirPathLen = 0;
    00102         }
    00103 }
    00104
    00106 bool DirWalker::GetNextFileOrDir(char* szFileName, size_t buffSize)
    00107 {
    00108         const char* sz;
    00109         size_t len;
    00110
    00111         // Clear out szFileName before hand in case something goes wrong.
    00112         *szFileName = '\0';
    00113
    00114         // Read next file
    00115 #ifdef WIN32
    00116         if (FindNextFile(hFile, &findData) == 0)
    00117                 return false;
    00118
    00119         sz = findData.cFileName;
    00120 #else
    00121         struct dirent* dp;
    00122
    00123         if ((dp = readdir(hFile)) == 0)
    00124                 return false;
    00125
    00126         sz = dp->d_name;
    00127 #endif
    00128
    00129         len = strlen(sz);
    00130
    00131         if (nDirPathLen + len > buffSize - 1)
    00132                 return false;
    00133
    00134         if (sz[0] == '.' && (len == 1 || (len == 2 && sz[1] == '.')))
    00135         {
    00136                 memcpy(szFileName, sz, len + 1);
    00137         }
    00138         else
    00139         {
    00140                 memcpy(szFileName, szDirPath, nDirPathLen);
    00141                 memcpy(szFileName + nDirPathLen, sz, len + 1);
    00142         }
    00143
    00144         return true;
    00145 }
    00146
    00158 bool DirWalker::GetNextFile(char* szFileName, size_t buffSize, char* szFileExt /*=NULL*/)
    00159 {
    00160         bool bSuccess;
    00161
    00162         do {
    00163                 bSuccess = GetNextFileOrDir(szFileName, buffSize);
    00164
    00165         } while(bSuccess && IsDirectory(szFileName));
    00166
    00167         if (szFileExt && bSuccess)
    00168         {
    00169                 *szFileExt = '\0'; // Init the string
    00170                 size_t len = strlen(szFileName + nDirPathLen);
    00171                 char* pEnd = szFileName + nDirPathLen + len - 1;
    00172
    00173                 for (int i = 0; i < 4; i++, pEnd--)
    00174                 {
    00175                         if (*pEnd == '.')
    00176                         {
    00177                                 strcpy(szFileExt, pEnd + 1);
    00178                                 break;
    00179                         }
    00180                 }
    00181         }
    00182
    00183         return bSuccess;
    00184 }
    00185
    00186 bool DirWalker::GetNextDir(char* szFileName, size_t buffSize)
    00187 {
    00188         bool bSuccess, bDotDirectory;
    00189
    00190         do {
    00191                 bSuccess = GetNextFileOrDir(szFileName, buffSize);
    00192
    00193                 // Ignore dot and dot-dot directory
    00194                 if (!strcmp(szFileName, ".") || !strcmp(szFileName, ".."))
    00195                         bDotDirectory = true;
    00196                 else
    00197                         bDotDirectory = false;
    00198
    00199         } while(bSuccess && (bDotDirectory || !IsDirectory(szFileName)));
    00200
    00201         return bSuccess;
    00202 }
    00203
    00204 /*static*/
    00205 bool DirWalker::IsDirectory(const char* szFileName)
    00206 {
    00207 #ifdef WIN32
    00208         DWORD info = GetFileAttributes(szFileName);
    00209         return (info & FILE_ATTRIBUTE_DIRECTORY) != 0;
    00210 #else
    00211         struct stat info;
    00212
    00213         if (stat(szFileName, &info) != 0)
    00214                 return false;
    00215         else
    00216                 return (info.st_mode & S_IFDIR) != 0;
    00217 #endif
    00218 }
    00219
    00220 /*static*/
    00221 const char* DirWalker::FindFileExtention(const char* szFileName)
    00222 {
    00223         size_t len = strlen(szFileName);
    00224         const char* pEnd = szFileName + len - 1;
    00225
    00226         for (; pEnd > szFileName && *pEnd != FILE_SEP; pEnd--)
    00227                 if (*pEnd == '.')
    00228                         return pEnd + 1;
    00229
    00230         return szFileName + len;
    00231 }
    00232
    00233 /*static*/
    00234 bool DirWalker::CompFileExt(const char* szFileName, const char* szFileExt)
    00235 {
    00236         return strcmp(szFileExt, FindFileExtention(szFileName)) == 0;
    00237 }
    00238
    00239 /*static*/
    00240 void DirWalker::ChangeFileExt(const char* szFileName, const char* szExt, char* szNewName)
    00241 {
    00242         const char* szOldExt = FindFileExtention(szFileName);
    00243         int nBytes = szOldExt - szFileName;
    00244
    00245         memcpy(szNewName, szFileName, nBytes);
    00246
    00247         if (szExt)
    00248         {
    00249                 if (szNewName[nBytes - 1] != '.')
    00250                         szNewName[nBytes++] = '.';
    00251
    00252                 strcpy(szNewName + nBytes, szExt);
    00253         }
    00254         /* szExt == NULL*/
    00255         else if (szNewName[nBytes - 1] == '.')
    00256                 szNewName[nBytes - 1] = '\0';
    00257         else
    00258                 szNewName[nBytes] = '\0';
    00259 }
    00260
    00264 /*static*/
    00265 int DirWalker::CompareLastModifDate(const char* szFileName1, const char* szFileName2)
    00266 {
    00267 #ifndef WIN32
    00268         struct stat info1, info2;
    00269
    00270         info1.st_mtime = info2.st_mtime = 0;
    00271
    00272         stat(szFileName1, &info1);
    00273         stat(szFileName2, &info2);
    00274
    00275         return info1.st_mtime - info2.st_mtime;
    00276 #else
    00277         return 0;
    00278 #endif
    00279
    00280 }
    00281
    00294 /*static*/
    00295 int DirWalker::CreateFileName(const char* szDirName, const char* szPrefix,
    00296                                                           const char* szFileExt, char szFileName[])
    00297 {
    00298         DirWalker dw;
    00299
    00300         *szFileName = '\0';     // just for safety
    00301
    00302         if (!DirWalker::IsDirectory(szDirName) || !dw.OpenDir(szDirName))
    00303                 return -1;
    00304
    00305         int nPrefixLen = strlen(szPrefix), nPathLen = dw.GetDirPathLen();
    00306         char szExt[10];
    00307         int n, nMax = -1;
    00308
    00309         while (dw.GetNextFile(szFileName, MAX_PATH, szExt))
    00310         {
    00311                 if (!strncmp(szPrefix, szFileName + nPathLen, nPrefixLen) &&
    00312                         !strcmp(szFileExt, szExt))
    00313                 {
    00314                         n = atoi(szFileName + nPathLen + nPrefixLen);
    00315
    00316                         if (n > nMax)
    00317                                 nMax = n;
    00318                 }
    00319         }
    00320
    00321         sprintf(szFileName, "%s%s%d.%s", dw.GetDirPath(), szPrefix, ++nMax, szFileExt);
    00322
    00323         return nMax;
    00324 }
    00325
    00328 /*int ReadDir(char* name)
    00329 {
    00330         DIR* dirp = opendir(".");
    00331         struct dirent* dp;
    00332         int errno;
    00333
    00334         while (dirp)
    00335         {
    00336                 errno = 0;
    00337
    00338                 if ((dp = readdir(dirp)) != NULL)
    00339                 {
    00340                         DBG_MSG(dp->d_name)
    00341                         if (strcmp(dp->d_name, name) == 0)
    00342                         {
    00343                                 closedir(dirp);
    00344                                 return FOUND;
    00345                         }
    00346                 }
    00347                 else
    00348                 {
    00349                         if (errno == 0)
    00350                         {
    00351                                 closedir(dirp);
    00352                                 return NOT_FOUND;
    00353                         }
    00354
    00355                         closedir(dirp);
    00356
    00357                         return READ_ERROR;
    00358                 }
    00359         }
    00360
    00361         return OPEN_ERROR;
    00362 }*/