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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1910 - (hide annotations) (download)
Fri Jun 5 14:22:20 2009 UTC (14 years, 10 months ago) by senoner
File size: 12554 byte(s)
* Added Instruments DB on Windows.
* Relative path support for DB file (stdalone and VST) not implemented yet

1 iliev 1717 /***************************************************************************
2     * *
3     * Copyright (C) 2008 Grigor Iliev, Benno Senoner *
4     * *
5     * This program is free software; you can redistribute it and/or modify *
6     * it under the terms of the GNU General Public License as published by *
7     * the Free Software Foundation; either version 2 of the License, or *
8     * (at your option) any later version. *
9     * *
10     * This program is distributed in the hope that it will be useful, *
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13     * GNU General Public License for more details. *
14     * *
15     * You should have received a copy of the GNU General Public License *
16     * along with this program; if not, write to the Free Software *
17     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
18     * MA 02110-1301 USA *
19     ***************************************************************************/
20    
21     #include "File.h"
22    
23 persson 1726 #include <cstring>
24 iliev 1717 #include <errno.h>
25     #include <sstream>
26    
27     #include "Exception.h"
28     #include "global_private.h"
29    
30     #if WIN32
31    
32 senoner 1910 /*
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 iliev 1717 #else
473     #include <dirent.h>
474     #include <ftw.h>
475     #endif
476    
477     namespace LinuxSampler {
478    
479     char File::DirSeparator = '/';
480    
481 senoner 1910 Mutex File::DirectoryWalkerMutex;
482 iliev 1717 std::vector<File::DirectoryWalker*> File::DirectoryWalkers;
483     std::string File::DWErrorMsg;
484    
485     File::File(std::string Path) {
486     bExist = !stat(Path.c_str(), &Status);
487     if(!bExist) ErrorMsg = strerror(errno);
488     }
489    
490     bool File::Exist() {
491     return bExist;
492     }
493    
494     std::string File::GetErrorMsg() {
495     return ErrorMsg;
496     }
497    
498     bool File::IsFile() {
499     if(!Exist()) return false;
500    
501     return S_ISREG(Status.st_mode);
502     }
503    
504     bool File::IsDirectory() {
505     if(!Exist()) return false;
506    
507     return S_ISDIR(Status.st_mode);
508     }
509    
510     unsigned long File::GetSize() {
511     if(!Exist()) return 0;
512    
513 senoner 1910 return Status.st_size;
514 iliev 1717 }
515    
516     FileListPtr File::GetFiles(std::string Dir) {
517     DIR* pDir = opendir(Dir.c_str());
518     if (pDir == NULL) {
519     std::stringstream ss;
520     ss << "Failed to list the directory content of `";
521     ss << Dir << "`: " << strerror(errno);
522     throw Exception(ss.str());
523     }
524    
525     FileListPtr fileList(new std::vector<std::string>);
526    
527     struct dirent* pEnt = readdir(pDir);
528     while (pEnt != NULL) {
529     if (pEnt->d_type != DT_REG) {
530     pEnt = readdir(pDir);
531     continue;
532     }
533    
534     fileList->push_back(std::string(pEnt->d_name));
535     pEnt = readdir(pDir);
536     }
537    
538     if (closedir(pDir)) {
539     std::stringstream ss;
540     ss << "Failed to close directory `" << Dir << "`: ";
541     ss << strerror(errno);
542     throw Exception(ss.str());
543     }
544    
545     return fileList;
546     }
547    
548     void File::WalkDirectoryTree(std::string Dir, DirectoryWalker* pWalker) {
549     dmsg(2,("File: WalkDirectoryTree(Dir=%s)\n", Dir.c_str()));
550     File f = File(Dir);
551     if(!f.Exist()) throw Exception("Fail to stat `" + Dir + "`: " + f.GetErrorMsg());
552     if(!f.IsDirectory()) throw Exception("The specified path is not a directory: " + Dir);
553    
554     DirectoryWalkerMutex.Lock();
555     DirectoryWalkers.push_back(pWalker);
556     DWErrorMsg = "Failed to process directory tree: " + Dir;
557    
558     if (ftw(Dir.c_str(), FtwCallback, 10)) {
559     DirectoryWalkers.pop_back();
560     if (DirectoryWalkers.size() == 0) DirectoryWalkerMutex.Unlock();
561     throw Exception(DWErrorMsg);
562     }
563     DirectoryWalkers.pop_back();
564     if (DirectoryWalkers.size() == 0) DirectoryWalkerMutex.Unlock();
565     }
566    
567    
568     int File::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {
569     dmsg(2,("File: FtwCallback(fpath=%s)\n", fpath));
570     try {
571     if (typeflag == FTW_D) DirectoryWalkers.back()->DirectoryEntry(std::string(fpath));
572     else if (typeflag == FTW_F) DirectoryWalkers.back()->FileEntry(std::string(fpath));
573     } catch(Exception e) {
574     e.PrintMessage();
575     DWErrorMsg = e.Message();
576     return -1;
577     }
578    
579     return 0;
580     };
581     }

  ViewVC Help
Powered by ViewVC