/[svn]/linuxsampler/trunk/src/common/File.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/common/File.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1782 by iliev, Tue Sep 30 02:16:41 2008 UTC revision 1910 by senoner, Fri Jun 5 14:22:20 2009 UTC
# Line 29  Line 29 
29    
30  #if WIN32  #if WIN32
31    
32    /*
33    dirent.c
34    POSIX WIN32 Directory Browsing parts
35    Copyright (C) 2005 OpenAsthra
36    blogs.openasthra AT gmail.com
37    modifications copyright 2009 by Benno Senoner
38    Licence: LGPL
39    */
40    
41    #include "dirent.h"
42    #include <errno.h>
43    #include <io.h>
44    #include <stdlib.h>
45    #include <string.h>
46    
47    struct DIR
48    {
49      long handle;
50      long int pos;
51      struct _finddata_t  info;
52      struct dirent d_ent;
53    };
54    
55    //aux functions
56    static int StripRegEx(char *name);
57    static int PreOrderTraversal(DIR *dirp, int (*fn) (const char *fpath, const struct stat *sb, int typeflag));
58    static int CallFn(int (*fn) (const char *fpath, const struct stat *sb, int typeflag), char *dirpath, DIR *dirp);
59    
60    
61    //posix directory browsing API implementation
62    
63    DIR *opendir(const char *name)
64    {
65      DIR *dir = NULL;
66      const char *all;
67      long len;
68      
69      if((NULL == name) || ('\0' == *name))
70      {
71        errno = EINVAL;
72        return dir;
73      }
74      
75      len = strlen(name);
76      all = strchr("/\\", name[len - 1]) ? "*" : "/*";
77        
78      len += strlen(all) + 1;
79    
80      dir = (DIR *) malloc((len*sizeof(char)) + sizeof(*dir));
81      if(NULL == dir)
82      {
83        errno = ENOMEM;
84        return NULL;
85      }
86        
87      dir->d_ent.d_namlen = len;
88      dir->pos = 0;
89      strcpy(dir->d_ent.d_name, name);
90      strcat(dir->d_ent.d_name, all);
91      dir->handle = (long) _findfirst(dir->d_ent.d_name, &dir->info);
92      if(dir->handle == -1)
93      {
94        free(dir);
95        dir = NULL;
96      }
97    
98      return dir;
99    }
100    
101    int closedir(DIR *dir)
102    {
103      int result = -1;
104    
105      if(dir)
106      {
107        if(dir->handle != -1)
108        {
109          result = _findclose(dir->handle);
110        }
111        free(dir);
112      }
113    
114      if(result == -1)
115      {
116        errno = EBADF;
117      }
118    
119      return result;
120    }
121    
122    struct dirent *readdir(DIR *dir)
123    {
124      struct dirent *result = 0;
125    
126      if(dir && dir->handle != -1)
127      {
128        if(_findnext(dir->handle, &dir->info) != -1)
129        {
130          result = &dir->d_ent;
131          strcpy(result->d_name, dir->info.name);
132              result->d_type = DT_REG;
133              if(dir->info.attrib & _A_SUBDIR) result->d_type = DT_DIR;
134          dir->pos ++;
135        }
136      }
137      else
138      {
139        errno = EBADF;
140      }
141    
142      return result;
143    }
144    
145    void rewinddir(DIR *dir)
146    {
147        if(dir && dir->handle != -1)
148        {
149            _findclose(dir->handle);
150            dir->handle = (long) _findfirst(dir->d_ent.d_name, &dir->info);
151            dir->pos = 0;
152        }
153        else
154        {
155            errno = EBADF;
156        }
157    }
158    
159    int     stat(const char *path, struct stat *buf)
160    {
161            struct _finddata_t  info;
162            long handle;
163            mode_t mode = 0;
164    
165            if(!buf | !path)
166                    return -1;
167    
168            handle = _findfirst(path, &info);
169            if(handle == -1)
170                return -1;
171            _findclose(handle);
172            
173            
174            buf->st_size = info.size;
175            buf->st_atime = info.time_access;
176            buf->st_ctime = info.time_create;
177    
178                    
179            /* | dir/regular | systemfile | readonly | write |*/
180            
181        mode = S_IFREG;
182            if(info.attrib & _A_SUBDIR) mode = S_IFDIR;
183            buf->st_mode = mode;
184    
185            return 0;
186    }
187    
188    int dirfd(DIR *dirp)
189    {
190      if (NULL == dirp)
191      {
192        return -1;
193      }
194    
195      return dirp->handle;
196    }
197    
198    void seekdir (DIR *dirp, long int pos)
199    {
200      long int i;
201    
202      if (NULL == dirp)
203      {
204        return;
205      }
206    
207      if (pos < 0)
208      {
209        pos = dirp->pos + pos;
210        _findclose(dirp->handle);
211        dirp->handle = (long) _findfirst(dirp->d_ent.d_name, &dirp->info);
212      }
213    
214      for (i=0; i<pos; i++)
215      {
216        if(_findnext(dirp->handle, &dirp->info) != -1)
217        {
218          dirp->pos ++;
219        }
220        else
221        {
222          break;
223        }
224      }
225    
226    }
227    
228    
229    long int telldir (DIR *dirp)
230    {
231      if (NULL == dirp)
232      {
233        return -1;
234      }
235    
236      return dirp->pos;
237    
238    }
239    
240    
241    int scandir(const char *dir, struct dirent ***namelist,
242          int (*filter)(const struct dirent *),
243          int (*compar)(const struct dirent **, const struct dirent **))
244    {
245      struct dirent *result = 0;
246       struct dirent **namlist;
247      int namelistlen = 0;
248      int num_enrties= 0;
249    
250      DIR *dirp = opendir(dir);
251    
252      if (NULL == dirp)
253      {
254        return -1;
255      }
256    
257      if(dirp && dirp->handle != -1)
258      {
259        while(_findnext(dirp->handle, &dirp->info) != -1)
260        {
261          num_enrties++;
262        }
263      }
264    
265      rewinddir(dirp);
266    
267      namlist = (struct dirent **) malloc(num_enrties * sizeof(struct dirent *));
268    
269      if (NULL == namlist)
270      {
271        closedir(dirp);
272        return namelistlen;
273      }
274    
275      if(dirp && dirp->handle != -1)
276      {
277        while(_findnext(dirp->handle, &dirp->info) != -1)
278        {
279          result = (struct dirent *) malloc(sizeof(struct dirent) + strlen(dirp->info.name) + 1);
280          strcpy(result->d_name, dirp->info.name);
281              result->d_type = DT_REG;
282              if(dirp->info.attrib & _A_SUBDIR) result->d_type = DT_DIR;
283          if (filter)
284          {
285            if (filter(result))
286            {
287              namlist[namelistlen] = result;
288              namelistlen++;
289            }
290          }
291          else
292          {
293            namlist[namelistlen] = result;
294            namelistlen++;
295          }
296        }
297      }
298    
299      //qdirsort(namlist, namelistlen, compar); //todo
300    
301      *namelist = namlist;
302    
303      closedir(dirp);
304    
305      return namelistlen;
306    }
307    
308    int ftw(const char *dirpath,
309            int (*fn) (const char *fpath, const struct stat *sb,
310            int typeflag),
311            int nopenfd)
312    {
313      struct dirent *result = 0;
314      struct dirent **namlist;
315      int namelistlen = 0;
316      int num_enrties= 0;
317      struct stat sb;
318      int typeflag = 0;
319    
320      DIR *dirp = opendir(dirpath);
321    
322      if (NULL == dirp)
323      {
324        return -1;
325      }
326    
327    
328      if (CallFn(fn, (char *)dirpath, dirp))
329      {
330        closedir(dirp);
331        return 0;
332      }
333    
334      if(dirp && (dirp->handle != -1))
335      {
336        while(_findnext(dirp->handle, &dirp->info) != -1)
337        {
338          if ((dirp->info.attrib & _A_SUBDIR) &&
339              (strcmp(dirp->info.name, ".")) && (strcmp(dirp->info.name, "..")))
340          {
341            if (PreOrderTraversal(dirp, fn)>0)
342            {
343              break;
344            }
345          }
346          else
347          {
348            if (CallFn(fn, dirp->info.name, dirp))
349            {
350              break;
351            }
352          }
353        }
354      }
355    
356      closedir(dirp);
357      return 0;
358    
359    }
360    
361    //aux functions
362    int StripRegEx(char *name)
363    {
364      char *t = strstr(name, "/*");
365      if (t)
366      {
367        *t='\0';
368      }
369      else
370      {
371        t = strstr(name, "\\*");
372        if (t)
373        {
374          *t='\0';
375        }
376      }
377    
378      return 0;
379    }
380    
381    int CallFn(int (*fn) (const char *fpath, const struct stat *sb,
382            int typeflag), char *dirpath, DIR *dirp)
383    {
384      struct stat sb;
385      int typeflag = 0;
386    
387      if (fn)
388      {
389        stat(dirpath, &sb);
390        if (dirp->info.attrib & _A_SUBDIR)
391        {
392          typeflag = FTW_D;
393        }
394        else
395        {
396          typeflag = FTW_F;
397        }
398        return fn(dirpath, &sb, typeflag);
399      }
400      return 0;
401    }
402    
403    
404    int PreOrderTraversal(DIR *dirp, int (*fn) (const char *fpath, const struct stat *sb, int typeflag))
405    {
406      DIR *dirp2;
407      struct stat sb;
408      int typeflag = 0;
409      char *tmpdirnam;
410        
411      StripRegEx(dirp->d_ent.d_name);
412    
413      tmpdirnam = (char *)malloc(strlen(dirp->d_ent.d_name)+strlen(dirp->info.name)+2);
414      if (!tmpdirnam)
415      {
416        return -1;
417      }
418    
419      strcpy(tmpdirnam, dirp->d_ent.d_name);
420      strcat(tmpdirnam, "/");
421      strcat(tmpdirnam, dirp->info.name);
422    
423      dirp2 = opendir(tmpdirnam);
424    
425      if (NULL == dirp2)
426      {
427        free(tmpdirnam);
428        return -1;
429      }
430    
431      if (CallFn(fn, tmpdirnam, dirp2))
432      {
433        free(tmpdirnam);
434        closedir(dirp2);
435        return 1;
436      }
437    
438      while(_findnext(dirp2->handle, &dirp2->info) != -1)
439        {
440          if (strcmp(dirp2->info.name, ".."))
441          {
442            if ((dirp2->info.attrib & _A_SUBDIR) && strcmp(dirp2->info.name, ".") && strcmp(dirp2->info.name, ".."))
443            {
444              if (PreOrderTraversal(dirp2, fn))
445              {
446                free(tmpdirnam);
447                closedir(dirp2);
448                return 1;
449              }
450            }
451            else
452            {
453              if (CallFn(fn, dirp2->info.name, dirp2))
454              {
455                free(tmpdirnam);
456                closedir(dirp2);
457                return 1;
458              }
459            }
460          } /*if (strcmp(dirp2->info.name, ".."))*/
461        }
462    
463       free(tmpdirnam);
464       closedir(dirp2);
465       return 0;
466      
467    }
468    
469    /* end of POSIX WIN32 Directory Browsing dirent.c implementation */
470    
471    
472  #else  #else
473  #include <dirent.h>  #include <dirent.h>
474  #include <ftw.h>  #include <ftw.h>
# Line 36  Line 476 
476    
477  namespace LinuxSampler {  namespace LinuxSampler {
478    
 #if WIN32  
     char File::DirSeparator = '\\';  
 #else  
479      char File::DirSeparator = '/';      char File::DirSeparator = '/';
 #endif  
480    
481      Mutex File::DirectoryWalkerMutex = Mutex();      Mutex File::DirectoryWalkerMutex;
482      std::vector<File::DirectoryWalker*> File::DirectoryWalkers;      std::vector<File::DirectoryWalker*> File::DirectoryWalkers;
483      std::string File::DWErrorMsg;      std::string File::DWErrorMsg;
484    
485      File::File(std::string Path) {      File::File(std::string Path) {
         #if WIN32  
           
         #else  
486              bExist = !stat(Path.c_str(), &Status);              bExist = !stat(Path.c_str(), &Status);
487              if(!bExist) ErrorMsg = strerror(errno);              if(!bExist) ErrorMsg = strerror(errno);
         #endif  
488      }      }
489            
490      bool File::Exist() {      bool File::Exist() {
# Line 66  namespace LinuxSampler { Line 498  namespace LinuxSampler {
498      bool File::IsFile() {      bool File::IsFile() {
499          if(!Exist()) return false;          if(!Exist()) return false;
500                    
         #if WIN32  
           
         #else  
501              return S_ISREG(Status.st_mode);              return S_ISREG(Status.st_mode);
         #endif  
502      }      }
503            
504      bool File::IsDirectory() {      bool File::IsDirectory() {
505          if(!Exist()) return false;          if(!Exist()) return false;
506                    
         #if WIN32  
           
         #else  
507              return S_ISDIR(Status.st_mode);              return S_ISDIR(Status.st_mode);
         #endif  
508      }      }
509            
510      unsigned long File::GetSize() {      unsigned long File::GetSize() {
511          if(!Exist()) return 0;          if(!Exist()) return 0;
512                    
513          #if WIN32              return Status.st_size;      
           
         #else  
             return Status.st_size;  
         #endif        
514      }      }
515            
516      FileListPtr File::GetFiles(std::string Dir) {      FileListPtr File::GetFiles(std::string Dir) {
         #if WIN32  
           
         #else  
517              DIR* pDir = opendir(Dir.c_str());              DIR* pDir = opendir(Dir.c_str());
518              if (pDir == NULL) {              if (pDir == NULL) {
519                  std::stringstream ss;                  std::stringstream ss;
# Line 126  namespace LinuxSampler { Line 543  namespace LinuxSampler {
543              }              }
544                            
545              return fileList;              return fileList;
         #endif  
546      }      }
547            
548      void File::WalkDirectoryTree(std::string Dir, DirectoryWalker* pWalker) {      void File::WalkDirectoryTree(std::string Dir, DirectoryWalker* pWalker) {
# Line 139  namespace LinuxSampler { Line 555  namespace LinuxSampler {
555          DirectoryWalkers.push_back(pWalker);          DirectoryWalkers.push_back(pWalker);
556          DWErrorMsg = "Failed to process directory tree: " + Dir;          DWErrorMsg = "Failed to process directory tree: " + Dir;
557                    
         #if WIN32  
           
         #else  
558              if (ftw(Dir.c_str(), FtwCallback, 10)) {              if (ftw(Dir.c_str(), FtwCallback, 10)) {
559                  DirectoryWalkers.pop_back();                  DirectoryWalkers.pop_back();
560                  if (DirectoryWalkers.size() == 0) DirectoryWalkerMutex.Unlock();                  if (DirectoryWalkers.size() == 0) DirectoryWalkerMutex.Unlock();
561                  throw Exception(DWErrorMsg);                  throw Exception(DWErrorMsg);
562              }              }
         #endif  
563          DirectoryWalkers.pop_back();          DirectoryWalkers.pop_back();
564          if (DirectoryWalkers.size() == 0) DirectoryWalkerMutex.Unlock();          if (DirectoryWalkers.size() == 0) DirectoryWalkerMutex.Unlock();
565      }      }
566    
 #if WIN32  
567    
 #else  
568      int File::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {      int File::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {
569          dmsg(2,("File: FtwCallback(fpath=%s)\n", fpath));          dmsg(2,("File: FtwCallback(fpath=%s)\n", fpath));
570          try {          try {
# Line 168  namespace LinuxSampler { Line 578  namespace LinuxSampler {
578                    
579          return 0;          return 0;
580      };      };
 #endif  
581  }  }

Legend:
Removed from v.1782  
changed lines
  Added in v.1910

  ViewVC Help
Powered by ViewVC