/[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 1943 - (hide annotations) (download)
Tue Jul 14 18:25:11 2009 UTC (14 years, 9 months ago) by persson
File size: 6345 byte(s)
* fixed instrument database recursive import, which was broken on
  Windows

1 iliev 1717 /***************************************************************************
2     * *
3 persson 1943 * Copyright (C) 2008 - 2009 Grigor Iliev, Benno Senoner *
4 iliev 1717 * *
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 senoner 1911 #include <sys/stat.h>
27 persson 1943 #include <dirent.h>
28 iliev 1717
29     #include "Exception.h"
30     #include "global_private.h"
31    
32     #if WIN32
33 persson 1943 #include <windows.h>
34 iliev 1717 #else
35     #include <ftw.h>
36     #endif
37    
38     namespace LinuxSampler {
39 persson 1943 #ifdef WIN32
40     char File::DirSeparator = '\\';
41     #else
42 iliev 1717 char File::DirSeparator = '/';
43 persson 1943 #endif
44 senoner 1910 Mutex File::DirectoryWalkerMutex;
45 iliev 1717 std::vector<File::DirectoryWalker*> File::DirectoryWalkers;
46     std::string File::DWErrorMsg;
47    
48     File::File(std::string Path) {
49     bExist = !stat(Path.c_str(), &Status);
50     if(!bExist) ErrorMsg = strerror(errno);
51     }
52    
53     bool File::Exist() {
54     return bExist;
55     }
56    
57     std::string File::GetErrorMsg() {
58     return ErrorMsg;
59     }
60    
61     bool File::IsFile() {
62     if(!Exist()) return false;
63    
64     return S_ISREG(Status.st_mode);
65     }
66    
67     bool File::IsDirectory() {
68     if(!Exist()) return false;
69    
70     return S_ISDIR(Status.st_mode);
71     }
72    
73     unsigned long File::GetSize() {
74     if(!Exist()) return 0;
75    
76 senoner 1910 return Status.st_size;
77 iliev 1717 }
78    
79     FileListPtr File::GetFiles(std::string Dir) {
80     DIR* pDir = opendir(Dir.c_str());
81     if (pDir == NULL) {
82     std::stringstream ss;
83     ss << "Failed to list the directory content of `";
84     ss << Dir << "`: " << strerror(errno);
85     throw Exception(ss.str());
86     }
87    
88     FileListPtr fileList(new std::vector<std::string>);
89    
90     struct dirent* pEnt = readdir(pDir);
91     while (pEnt != NULL) {
92 persson 1943 #ifdef _DIRENT_HAVE_D_TYPE
93     if (pEnt->d_type == DT_REG) {
94 iliev 1717 fileList->push_back(std::string(pEnt->d_name));
95 persson 1943 }
96     #else
97     struct stat s;
98     if (stat((Dir + DirSeparator + pEnt->d_name).c_str(), &s) == 0 && S_ISREG(s.st_mode)) {
99     fileList->push_back(std::string(pEnt->d_name));
100     }
101     #endif
102 iliev 1717 pEnt = readdir(pDir);
103     }
104    
105     if (closedir(pDir)) {
106     std::stringstream ss;
107     ss << "Failed to close directory `" << Dir << "`: ";
108     ss << strerror(errno);
109     throw Exception(ss.str());
110     }
111    
112     return fileList;
113     }
114    
115     void File::WalkDirectoryTree(std::string Dir, DirectoryWalker* pWalker) {
116     dmsg(2,("File: WalkDirectoryTree(Dir=%s)\n", Dir.c_str()));
117     File f = File(Dir);
118     if(!f.Exist()) throw Exception("Fail to stat `" + Dir + "`: " + f.GetErrorMsg());
119     if(!f.IsDirectory()) throw Exception("The specified path is not a directory: " + Dir);
120 persson 1943 #ifdef WIN32
121     WalkDirectoryTreeSub(Dir, pWalker);
122     #else
123 iliev 1717 DirectoryWalkerMutex.Lock();
124     DirectoryWalkers.push_back(pWalker);
125     DWErrorMsg = "Failed to process directory tree: " + Dir;
126    
127     if (ftw(Dir.c_str(), FtwCallback, 10)) {
128     DirectoryWalkers.pop_back();
129     if (DirectoryWalkers.size() == 0) DirectoryWalkerMutex.Unlock();
130     throw Exception(DWErrorMsg);
131     }
132     DirectoryWalkers.pop_back();
133     if (DirectoryWalkers.size() == 0) DirectoryWalkerMutex.Unlock();
134 persson 1943 #endif
135 iliev 1717 }
136    
137 persson 1943 #ifdef WIN32
138     void File::WalkDirectoryTreeSub(String Dir, DirectoryWalker* pWalker) {
139     dmsg(2,("File: WalkDirectoryTreeSub(Dir=%s)\n", Dir.c_str()));
140     DWORD attrs = GetFileAttributes(Dir.c_str());
141     if (attrs == INVALID_FILE_ATTRIBUTES) return;
142 iliev 1717
143 persson 1943 if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
144     pWalker->DirectoryEntry(Dir);
145    
146     std::string::size_type l = Dir.length() - 1;
147     if (Dir[l] == '/') Dir[l] = '\\';
148     else if (Dir[l] != '\\') Dir += '\\';
149    
150     WIN32_FIND_DATA fd;
151     HANDLE h = FindFirstFile((Dir + "*").c_str(), &fd);
152     if (h == INVALID_HANDLE_VALUE) return;
153     do {
154     if (strcmp(fd.cFileName, ".") != 0 &&
155     strcmp(fd.cFileName, "..") != 0) {
156     WalkDirectoryTreeSub(Dir + fd.cFileName, pWalker);
157     }
158     } while (FindNextFile(h, &fd));
159     FindClose(h);
160     } else {
161     pWalker->FileEntry(Dir);
162     }
163     }
164     #else
165 iliev 1717 int File::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {
166     dmsg(2,("File: FtwCallback(fpath=%s)\n", fpath));
167     try {
168     if (typeflag == FTW_D) DirectoryWalkers.back()->DirectoryEntry(std::string(fpath));
169     else if (typeflag == FTW_F) DirectoryWalkers.back()->FileEntry(std::string(fpath));
170     } catch(Exception e) {
171     e.PrintMessage();
172     DWErrorMsg = e.Message();
173     return -1;
174     }
175    
176     return 0;
177 persson 1943 }
178     #endif
179 iliev 1717 }

  ViewVC Help
Powered by ViewVC