- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/Programmation/Sources/Tensor2/Utils/src/frost_utils_directory.cpp

Go to the documentation of this file.

    00001 /* ###################################### */
    00002 /* ###     Frost Engine, by Kalith    ### */
    00003 /* ###################################### */
    00004 /*                                        */
    00005
    00006 #include "frost_utils_directory.h"
    00007 #include "frost_utils_stdhelper.h"
    00008
    00009 #include <sys/types.h>
    00010 #include <sys/stat.h>
    00011
    00012 #ifdef FROST_LINUX
    00013     // Emulate directory and file listing windows functions
    00014     // Note : Taken directly from Ogre3D
    00015     // http://www.ogre3d.org/
    00016
    00017     #include <dirent.h>
    00018     #include <unistd.h>
    00019     #include <fnmatch.h>
    00020     #include <cstring>
    00021     #include <cstdio>
    00022
    00023     struct _finddata_t
    00024     {
    00025         char *name;
    00026         int attrib;
    00027         unsigned long size;
    00028     };
    00029     struct _find_search_t
    00030     {
    00031         char *pattern;
    00032         char *curfn;
    00033         char *directory;
    00034         int dirlen;
    00035         DIR *dirfd;
    00036     };
    00037
    00038     #define _A_NORMAL 0x00  /* Normalfile-Noread/writerestrictions */
    00039     #define _A_RDONLY 0x01  /* Read only file */
    00040     #define _A_HIDDEN 0x02  /* Hidden file */
    00041     #define _A_SYSTEM 0x04  /* System file */
    00042     #define _A_SUBDIR 0x10  /* Subdirectory */
    00043     #define _A_ARCH   0x20  /* Archive file */
    00044
    00045     int _findclose(long id);
    00046     int _findnext(long id, struct _finddata_t *data);
    00047
    00048     long _findfirst(const char *pattern, struct _finddata_t *data)
    00049     {
    00050         _find_search_t *fs = new _find_search_t;
    00051         fs->curfn = NULL;
    00052         fs->pattern = NULL;
    00053
    00054         const char *mask = strrchr(pattern, '/');
    00055         if (mask)
    00056         {
    00057             fs->dirlen = mask - pattern;
    00058             mask++;
    00059             fs->directory = (char *)malloc(fs->dirlen + 1);
    00060             memcpy(fs->directory, pattern, fs->dirlen);
    00061             fs->directory [fs->dirlen] = 0;
    00062         }
    00063         else
    00064         {
    00065             mask = pattern;
    00066             fs->directory = strdup(".");
    00067             fs->dirlen = 1;
    00068         }
    00069
    00070         fs->dirfd = opendir(fs->directory);
    00071         if (!fs->dirfd)
    00072         {
    00073             _findclose((long)fs);
    00074             return -1;
    00075         }
    00076
    00077         if (strcmp(mask, "*.*") == 0)
    00078             mask += 2;
    00079         fs->pattern = strdup(mask);
    00080
    00081         if (_findnext((long)fs, data) < 0)
    00082         {
    00083             _findclose((long)fs);
    00084             return -1;
    00085         }
    00086
    00087         return (long)fs;
    00088     }
    00089
    00090     int _findnext(long id, struct _finddata_t *data)
    00091     {
    00092         _find_search_t *fs = (_find_search_t*)id;
    00093
    00094         dirent *entry;
    00095         for (;;)
    00096         {
    00097             if (!(entry = readdir(fs->dirfd)))
    00098                 return -1;
    00099
    00100             if (fnmatch(fs->pattern, entry->d_name, 0) == 0)
    00101                 break;
    00102         }
    00103
    00104         if (fs->curfn)
    00105             free(fs->curfn);
    00106         data->name = fs->curfn = strdup(entry->d_name);
    00107
    00108         size_t namelen = strlen(entry->d_name);
    00109         char *xfn = new char [fs->dirlen + 1 + namelen + 1];
    00110         sprintf(xfn, "%s/%s", fs->directory, entry->d_name);
    00111
    00112         struct stat stat_buf;
    00113         if (stat(xfn, &stat_buf))
    00114         {
    00115             data->attrib = _A_NORMAL;
    00116             data->size = 0;
    00117         }
    00118         else
    00119         {
    00120             if (S_ISDIR(stat_buf.st_mode))
    00121                 data->attrib = _A_SUBDIR;
    00122             else
    00123                 data->attrib = _A_NORMAL;
    00124
    00125             data->size = stat_buf.st_size;
    00126         }
    00127
    00128         delete [] xfn;
    00129
    00130         if (data->name [0] == '.')
    00131             data->attrib |= _A_HIDDEN;
    00132
    00133         return 0;
    00134     }
    00135
    00136     int _findclose(long id)
    00137     {
    00138         int ret;
    00139         _find_search_t *fs = (_find_search_t *)id;
    00140
    00141         ret = fs->dirfd ? closedir(fs->dirfd) : 0;
    00142         free(fs->pattern);
    00143         free(fs->directory);
    00144         if (fs->curfn)
    00145             free(fs->curfn);
    00146         delete fs;
    00147
    00148         return ret;
    00149     }
    00150 #else
    00151     #include <windows.h>
    00152     #include <direct.h>
    00153     #include <io.h>
    00154 #endif
    00155
    00156 using namespace std;
    00157
    00158 namespace Frost
    00159 {
    00160     const s_str Directory::CLASS_NAME = "Directory";
    00161
    00162     Directory::Directory( const s_str& sRelPath )
    00163     {
    00164         uiIter_ = 0u;
    00165         sRelPath_ = sRelPath;
    00166         sName_ = sRelPath_.Cut("/").Back();
    00167
    00168         s_ctnr<s_str> lDirList;
    00169
    00170         long lHandle, res;
    00171         struct _finddata_t tagData;
    00172
    00173         s_str sPattern;
    00174         if (sRelPath.IsEmpty())
    00175             sPattern = "*";
    00176         else
    00177             sPattern = sRelPath_ + "/*";
    00178
    00179         lHandle = _findfirst(sPattern.c_str(), &tagData);
    00180         res = 0;
    00181         while (lHandle != -1 && res != -1)
    00182         {
    00183             if ((tagData.attrib & _A_HIDDEN) != 0)
    00184             {
    00185                 res = _findnext(lHandle, &tagData);
    00186                 continue;
    00187             }
    00188
    00189             if ((tagData.attrib & _A_SUBDIR) != 0)
    00190             {
    00191                 s_str s = tagData.name;
    00192                 if (s != "." && s != "..")
    00193                     lDirList.PushBack(s);
    00194             }
    00195             else
    00196                 lFileList_.PushBack(tagData.name);
    00197
    00198             res = _findnext(lHandle, &tagData);
    00199         }
    00200
    00201         if(lHandle != -1)
    00202             _findclose(lHandle);
    00203
    00204         s_ctnr<s_str>::iterator iter;
    00205         foreach (iter, lDirList)
    00206         {
    00207             lSubDirectoryList_.PushBack(s_refptr<Directory>(new Directory(
    00208                 sRelPath_.IsEmpty() ? (*iter) : (sRelPath_ + "/" + (*iter))
    00209             )));
    00210         }
    00211     }
    00212
    00213     s_wptr<Directory> Directory::GetNextSubDirectory()
    00214     {
    00215         s_wptr<Directory> pSub;
    00216         if (uiIter_ < lSubDirectoryList_.GetSize())
    00217         {
    00218             pSub = lSubDirectoryList_[uiIter_];
    00219             ++uiIter_;
    00220         }
    00221         else
    00222             uiIter_ = 0u;
    00223
    00224         return pSub;
    00225     }
    00226
    00227     s_ctnr<s_str> Directory::GetFileList( const s_bool& bWithPath, const s_str& sExtensionFilter ) const
    00228     {
    00229         if (sExtensionFilter.IsEmpty())
    00230         {
    00231             if (bWithPath)
    00232             {
    00233                 s_ctnr<s_str> lNewFileList;
    00234
    00235                 s_ctnr<s_str>::const_iterator iterFile;
    00236                 foreach (iterFile, lFileList_)
    00237                 {
    00238                     lNewFileList.PushBack(sRelPath_ + "/" + (*iterFile));
    00239                 }
    00240
    00241                 return lNewFileList;
    00242             }
    00243             else
    00244             {
    00245                 return lFileList_;
    00246             }
    00247         }
    00248         else
    00249         {
    00250             s_ctnr<s_str> lNewFileList;
    00251
    00252             s_ctnr<s_str> lExtension = sExtensionFilter.Cut(",");
    00253             s_ctnr<s_str>::iterator iterExtension;
    00254             foreach (iterExtension, lExtension)
    00255             {
    00256                 iterExtension->Trim(' ');
    00257             }
    00258
    00259             s_ctnr<s_str>::const_iterator iterFile;
    00260             foreach (iterFile, lFileList_)
    00261             {
    00262                 s_str sExtension = iterFile->Cut(".", 1).Back();
    00263                 foreach (iterExtension, lExtension)
    00264                 {
    00265                     if (sExtension == (*iterExtension))
    00266                     {
    00267                         if (bWithPath)
    00268                             lNewFileList.PushBack(sRelPath_ + "/" + (*iterFile));
    00269                         else
    00270                             lNewFileList.PushBack(*iterFile);
    00271                         break;
    00272                     }
    00273                 }
    00274             }
    00275
    00276             return lNewFileList;
    00277         }
    00278     }
    00279
    00280     s_ctnr<s_str> Directory::GetRecursiveFileList(const s_bool& bWithPath, const s_str& sExtensionFilter) const
    00281     {
    00282         s_ctnr<s_str> lFileList = GetFileList(bWithPath, sExtensionFilter);
    00283
    00284         s_ctnr< s_refptr<Directory> >::const_iterator iterSubDir;
    00285         foreach (iterSubDir, lSubDirectoryList_)
    00286         {
    00287             lFileList.PushBack((*iterSubDir)->GetRecursiveFileList(bWithPath, sExtensionFilter));
    00288         }
    00289
    00290         return lFileList;
    00291     }
    00292
    00293     const s_str& Directory::GetName() const
    00294     {
    00295         return sName_;
    00296     }
    00297
    00298     const s_str& Directory::GetRelPath() const
    00299     {
    00300         return sRelPath_;
    00301     }
    00302
    00303     s_bool Directory::Exists(const s_str& sPath)
    00304     {
    00305 #ifdef FROST_LINUX
    00306         struct stat mStatus;
    00307         return stat(sPath.c_str(), &mStatus) == 0;
    00308 #else
    00309         if (access(sPath.c_str(), 0) == 0)
    00310         {
    00311             struct stat mStatus;
    00312             stat(sPath.c_str(), &mStatus);
    00313
    00314             if (mStatus.st_mode & S_IFDIR)
    00315                 return true;
    00316         }
    00317
    00318         return false;
    00319 #endif
    00320     }
    00321
    00322     s_bool Directory::Make(const s_str& sPath)
    00323     {
    00324         s_str sTemp = sPath;
    00325         sTemp.Replace("\\", "/");
    00326         s_ctnr<s_str> lDirs = sTemp.Cut("/");
    00327         sTemp = "";
    00328
    00329         s_ctnr<s_str>::iterator iter;
    00330         foreach (iter, lDirs)
    00331         {
    00332             if (iter->IsEmpty())
    00333                 continue;
    00334
    00335             if (sTemp.IsEmpty())
    00336                 sTemp = *iter;
    00337             else
    00338                 sTemp += "/" + *iter;
    00339
    00340             if (!Exists(sTemp))
    00341                 if (!Make_(sTemp))
    00342                     return false;
    00343         }
    00344
    00345         return true;
    00346     }
    00347
    00348     s_bool Directory::Make_(const s_str& sPath)
    00349     {
    00350 #ifdef FROST_LINUX
    00351         return mkdir(sPath.c_str(), 0777) == 0;
    00352 #else
    00353         return CreateDirectory(sPath.c_str(), 0) != 0;
    00354 #endif
    00355     }
    00356 }