(file) Return to File.cpp CVS log (file) (dir) Up to [ls] / linuxsampler / src / common

Diff for /linuxsampler/src/common/File.cpp between version 1.6 and 1.7

This file is part of LinuxSampler, which is licensed under the GNU GPL with the exception that USAGE of the source code, libraries and applications FOR COMMERCIAL HARDWARE OR SOFTWARE PRODUCTS IS NOT ALLOWED without prior written permission by the LinuxSampler authors. If you have questions on the subject, that are not yet covered by the FAQ, please contact us.


version 1.6, 2009/06/06 13:50:36 version 1.7, 2009/07/14 18:25:11
Line 1 
Line 1 
 /*************************************************************************** /***************************************************************************
  *                                                                         *  *                                                                         *
  *   Copyright (C) 2008 Grigor Iliev, Benno Senoner                        *   *   Copyright (C) 2008 - 2009 Grigor Iliev, Benno Senoner                 *
  *                                                                         *  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *  *   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  *  *   it under the terms of the GNU General Public License as published by  *
Line 24 
Line 24 
 #include <errno.h> #include <errno.h>
 #include <sstream> #include <sstream>
 #include <sys/stat.h> #include <sys/stat.h>
   #include <dirent.h>
  
 #include "Exception.h" #include "Exception.h"
 #include "global_private.h" #include "global_private.h"
  
 #if WIN32 #if WIN32
   #include <windows.h>
 /*  
 dirent.c  
 POSIX WIN32 Directory Browsing parts  
 Copyright (C) 2005 OpenAsthra  
 blogs.openasthra AT gmail.com  
 modifications copyright 2009 by Benno Senoner  
 Licence: LGPL  
 */  
   
 #include "dirent.h"  
 #include <errno.h>  
 #include <io.h>  
 #include <stdlib.h>  
 #include <string.h>  
   
 struct DIR  
 {  
   long handle;  
   long int pos;  
   struct _finddata_t  info;  
   struct dirent d_ent;  
 };  
   
 //aux functions  
 static int StripRegEx(char *name);  
 static int PreOrderTraversal(DIR *dirp, int (*fn) (const char *fpath, const struct stat *sb, int typeflag));  
 static int CallFn(int (*fn) (const char *fpath, const struct stat *sb, int typeflag), char *dirpath, DIR *dirp);  
   
   
 //posix directory browsing API implementation  
   
 DIR *opendir(const char *name)  
 {  
   DIR *dir = NULL;  
   const char *all;  
   long len;  
   
   if((NULL == name) || ('\0' == *name))  
   {  
     errno = EINVAL;  
     return dir;  
   }  
   
   len = strlen(name);  
   all = strchr("/\\", name[len - 1]) ? "*" : "/*";  
   
   len += strlen(all) + 1;  
   
   dir = (DIR *) malloc((len*sizeof(char)) + sizeof(*dir));  
   if(NULL == dir)  
   {  
     errno = ENOMEM;  
     return NULL;  
   }  
   
   dir->d_ent.d_namlen = len;  
   dir->pos = 0;  
   strcpy(dir->d_ent.d_name, name);  
   strcat(dir->d_ent.d_name, all);  
   dir->handle = (long) _findfirst(dir->d_ent.d_name, &dir->info);  
   if(dir->handle == -1)  
   {  
     free(dir);  
     dir = NULL;  
   }  
   
   return dir;  
 }  
   
 int closedir(DIR *dir)  
 {  
   int result = -1;  
   
   if(dir)  
   {  
     if(dir->handle != -1)  
     {  
       result = _findclose(dir->handle);  
     }  
     free(dir);  
   }  
   
   if(result == -1)  
   {  
     errno = EBADF;  
   }  
   
   return result;  
 }  
   
 struct dirent *readdir(DIR *dir)  
 {  
   struct dirent *result = 0;  
   
   if(dir && dir->handle != -1)  
   {  
     if(_findnext(dir->handle, &dir->info) != -1)  
     {  
       result = &dir->d_ent;  
       strcpy(result->d_name, dir->info.name);  
           result->d_type = DT_REG;  
           if(dir->info.attrib & _A_SUBDIR) result->d_type = DT_DIR;  
       dir->pos ++;  
     }  
   }  
   else  
   {  
     errno = EBADF;  
   }  
   
   return result;  
 }  
   
 void rewinddir(DIR *dir)  
 {  
     if(dir && dir->handle != -1)  
     {  
         _findclose(dir->handle);  
         dir->handle = (long) _findfirst(dir->d_ent.d_name, &dir->info);  
         dir->pos = 0;  
     }  
     else  
     {  
         errno = EBADF;  
     }  
 }  
   
 int dirfd(DIR *dirp)  
 {  
   if (NULL == dirp)  
   {  
     return -1;  
   }  
   
   return dirp->handle;  
 }  
   
 void seekdir (DIR *dirp, long int pos)  
 {  
   long int i;  
   
   if (NULL == dirp)  
   {  
     return;  
   }  
   
   if (pos < 0)  
   {  
     pos = dirp->pos + pos;  
     _findclose(dirp->handle);  
     dirp->handle = (long) _findfirst(dirp->d_ent.d_name, &dirp->info);  
   }  
   
   for (i=0; i<pos; i++)  
   {  
     if(_findnext(dirp->handle, &dirp->info) != -1)  
     {  
       dirp->pos ++;  
     }  
     else  
     {  
       break;  
     }  
   }  
   
 }  
   
   
 long int telldir (DIR *dirp)  
 {  
   if (NULL == dirp)  
   {  
     return -1;  
   }  
   
   return dirp->pos;  
   
 }  
   
   
 int scandir(const char *dir, struct dirent ***namelist,  
       int (*filter)(const struct dirent *),  
       int (*compar)(const struct dirent **, const struct dirent **))  
 {  
   struct dirent *result = 0;  
    struct dirent **namlist;  
   int namelistlen = 0;  
   int num_enrties= 0;  
   
   DIR *dirp = opendir(dir);  
   
   if (NULL == dirp)  
   {  
     return -1;  
   }  
   
   if(dirp && dirp->handle != -1)  
   {  
     while(_findnext(dirp->handle, &dirp->info) != -1)  
     {  
       num_enrties++;  
     }  
   }  
   
   rewinddir(dirp);  
   
   namlist = (struct dirent **) malloc(num_enrties * sizeof(struct dirent *));  
   
   if (NULL == namlist)  
   {  
     closedir(dirp);  
     return namelistlen;  
   }  
   
   if(dirp && dirp->handle != -1)  
   {  
     while(_findnext(dirp->handle, &dirp->info) != -1)  
     {  
       result = (struct dirent *) malloc(sizeof(struct dirent) + strlen(dirp->info.name) + 1);  
       strcpy(result->d_name, dirp->info.name);  
           result->d_type = DT_REG;  
           if(dirp->info.attrib & _A_SUBDIR) result->d_type = DT_DIR;  
       if (filter)  
       {  
         if (filter(result))  
         {  
           namlist[namelistlen] = result;  
           namelistlen++;  
         }  
       }  
       else  
       {  
         namlist[namelistlen] = result;  
         namelistlen++;  
       }  
     }  
   }  
   
   //qdirsort(namlist, namelistlen, compar); //todo  
   
   *namelist = namlist;  
   
   closedir(dirp);  
   
   return namelistlen;  
 }  
   
 int ftw(const char *dirpath,  
         int (*fn) (const char *fpath, const struct stat *sb,  
         int typeflag),  
         int nopenfd)  
 {  
   struct dirent *result = 0;  
   struct dirent **namlist;  
   int namelistlen = 0;  
   int num_enrties= 0;  
   struct stat sb;  
   int typeflag = 0;  
   
   DIR *dirp = opendir(dirpath);  
   
   if (NULL == dirp)  
   {  
     return -1;  
   }  
   
   
   if (CallFn(fn, (char *)dirpath, dirp))  
   {  
     closedir(dirp);  
     return 0;  
   }  
   
   if(dirp && (dirp->handle != -1))  
   {  
     while(_findnext(dirp->handle, &dirp->info) != -1)  
     {  
       if ((dirp->info.attrib & _A_SUBDIR) &&  
           (strcmp(dirp->info.name, ".")) && (strcmp(dirp->info.name, "..")))  
       {  
         if (PreOrderTraversal(dirp, fn)>0)  
         {  
           break;  
         }  
       }  
       else  
       {  
         if (CallFn(fn, dirp->info.name, dirp))  
         {  
           break;  
         }  
       }  
     }  
   }  
   
   closedir(dirp);  
   return 0;  
   
 }  
   
 //aux functions  
 int StripRegEx(char *name)  
 {  
   char *t = strstr(name, "/*");  
   if (t)  
   {  
     *t='\0';  
   }  
   else  
   {  
     t = strstr(name, "\\*");  
     if (t)  
     {  
       *t='\0';  
     }  
   }  
   
   return 0;  
 }  
   
 int CallFn(int (*fn) (const char *fpath, const struct stat *sb,  
         int typeflag), char *dirpath, DIR *dirp)  
 {  
   struct stat sb;  
   int typeflag = 0;  
   
   if (fn)  
   {  
     stat(dirpath, &sb);  
     if (dirp->info.attrib & _A_SUBDIR)  
     {  
       typeflag = FTW_D;  
     }  
     else  
     {  
       typeflag = FTW_F;  
     }  
     return fn(dirpath, &sb, typeflag);  
   }  
   return 0;  
 }  
   
   
 int PreOrderTraversal(DIR *dirp, int (*fn) (const char *fpath, const struct stat *sb, int typeflag))  
 {  
   DIR *dirp2;  
   struct stat sb;  
   int typeflag = 0;  
   char *tmpdirnam;  
   
   StripRegEx(dirp->d_ent.d_name);  
   
   tmpdirnam = (char *)malloc(strlen(dirp->d_ent.d_name)+strlen(dirp->info.name)+2);  
   if (!tmpdirnam)  
   {  
     return -1;  
   }  
   
   strcpy(tmpdirnam, dirp->d_ent.d_name);  
   strcat(tmpdirnam, "/");  
   strcat(tmpdirnam, dirp->info.name);  
   
   dirp2 = opendir(tmpdirnam);  
   
   if (NULL == dirp2)  
   {  
     free(tmpdirnam);  
     return -1;  
   }  
   
   if (CallFn(fn, tmpdirnam, dirp2))  
   {  
     free(tmpdirnam);  
     closedir(dirp2);  
     return 1;  
   }  
   
   while(_findnext(dirp2->handle, &dirp2->info) != -1)  
     {  
       if (strcmp(dirp2->info.name, ".."))  
       {  
         if ((dirp2->info.attrib & _A_SUBDIR) && strcmp(dirp2->info.name, ".") && strcmp(dirp2->info.name, ".."))  
         {  
           if (PreOrderTraversal(dirp2, fn))  
           {  
             free(tmpdirnam);  
             closedir(dirp2);  
             return 1;  
           }  
         }  
         else  
         {  
           if (CallFn(fn, dirp2->info.name, dirp2))  
           {  
             free(tmpdirnam);  
             closedir(dirp2);  
             return 1;  
           }  
         }  
       } /*if (strcmp(dirp2->info.name, ".."))*/  
     }  
   
    free(tmpdirnam);  
    closedir(dirp2);  
    return 0;  
   
 }  
   
 /* end of POSIX WIN32 Directory Browsing dirent.c implementation */  
   
   
 #else #else
 #include <dirent.h>  
 #include <ftw.h> #include <ftw.h>
 #endif #endif
  
 namespace LinuxSampler { namespace LinuxSampler {
   #ifdef WIN32
       char File::DirSeparator = '\\';
   #else
     char File::DirSeparator = '/';     char File::DirSeparator = '/';
   #endif
     Mutex File::DirectoryWalkerMutex;     Mutex File::DirectoryWalkerMutex;
     std::vector<File::DirectoryWalker*> File::DirectoryWalkers;     std::vector<File::DirectoryWalker*> File::DirectoryWalkers;
     std::string File::DWErrorMsg;     std::string File::DWErrorMsg;
Line 498 
Line 89 
  
             struct dirent* pEnt = readdir(pDir);             struct dirent* pEnt = readdir(pDir);
             while (pEnt != NULL) {             while (pEnt != NULL) {
                 if (pEnt->d_type != DT_REG) {  #ifdef _DIRENT_HAVE_D_TYPE
                     pEnt = readdir(pDir);              if (pEnt->d_type == DT_REG) {
                     continue;                  fileList->push_back(std::string(pEnt->d_name));
                 }                 }
   #else
               struct stat s;
               if (stat((Dir + DirSeparator + pEnt->d_name).c_str(), &s) == 0 && S_ISREG(s.st_mode)) {
                 fileList->push_back(std::string(pEnt->d_name));                 fileList->push_back(std::string(pEnt->d_name));
               }
   #endif
                 pEnt = readdir(pDir);                 pEnt = readdir(pDir);
             }             }
  
Line 522 
Line 117 
         File f = File(Dir);         File f = File(Dir);
         if(!f.Exist()) throw Exception("Fail to stat `" + Dir + "`: " + f.GetErrorMsg());         if(!f.Exist()) throw Exception("Fail to stat `" + Dir + "`: " + f.GetErrorMsg());
         if(!f.IsDirectory()) throw Exception("The specified path is not a directory: " + Dir);         if(!f.IsDirectory()) throw Exception("The specified path is not a directory: " + Dir);
   #ifdef WIN32
           WalkDirectoryTreeSub(Dir, pWalker);
   #else
         DirectoryWalkerMutex.Lock();         DirectoryWalkerMutex.Lock();
         DirectoryWalkers.push_back(pWalker);         DirectoryWalkers.push_back(pWalker);
         DWErrorMsg = "Failed to process directory tree: " + Dir;         DWErrorMsg = "Failed to process directory tree: " + Dir;
Line 534 
Line 131 
             }             }
         DirectoryWalkers.pop_back();         DirectoryWalkers.pop_back();
         if (DirectoryWalkers.size() == 0) DirectoryWalkerMutex.Unlock();         if (DirectoryWalkers.size() == 0) DirectoryWalkerMutex.Unlock();
   #endif
     }     }
  
   #ifdef WIN32
       void File::WalkDirectoryTreeSub(String Dir, DirectoryWalker* pWalker) {
           dmsg(2,("File: WalkDirectoryTreeSub(Dir=%s)\n", Dir.c_str()));
           DWORD attrs = GetFileAttributes(Dir.c_str());
           if (attrs == INVALID_FILE_ATTRIBUTES) return;
   
           if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
               pWalker->DirectoryEntry(Dir);
   
               std::string::size_type l = Dir.length() - 1;
               if (Dir[l] == '/') Dir[l] = '\\';
               else if (Dir[l] != '\\') Dir += '\\';
   
               WIN32_FIND_DATA fd;
               HANDLE h = FindFirstFile((Dir + "*").c_str(), &fd);
               if (h == INVALID_HANDLE_VALUE) return;
               do {
                   if (strcmp(fd.cFileName, ".") != 0 &&
                       strcmp(fd.cFileName, "..") != 0) {
                       WalkDirectoryTreeSub(Dir + fd.cFileName, pWalker);
                   }
               } while (FindNextFile(h, &fd));
               FindClose(h);
           } else {
               pWalker->FileEntry(Dir);
           }
       }
   #else
     int File::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {     int File::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {
         dmsg(2,("File: FtwCallback(fpath=%s)\n", fpath));         dmsg(2,("File: FtwCallback(fpath=%s)\n", fpath));
         try {         try {
Line 549 
Line 174 
         }         }
  
         return 0;         return 0;
     };      }
   #endif
 } }


Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

LinuxSampler Developers
Powered by
ViewCVS