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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1943 - (show 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 /***************************************************************************
2 * *
3 * Copyright (C) 2008 - 2009 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 #include <cstring>
24 #include <errno.h>
25 #include <sstream>
26 #include <sys/stat.h>
27 #include <dirent.h>
28
29 #include "Exception.h"
30 #include "global_private.h"
31
32 #if WIN32
33 #include <windows.h>
34 #else
35 #include <ftw.h>
36 #endif
37
38 namespace LinuxSampler {
39 #ifdef WIN32
40 char File::DirSeparator = '\\';
41 #else
42 char File::DirSeparator = '/';
43 #endif
44 Mutex File::DirectoryWalkerMutex;
45 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 return Status.st_size;
77 }
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 #ifdef _DIRENT_HAVE_D_TYPE
93 if (pEnt->d_type == DT_REG) {
94 fileList->push_back(std::string(pEnt->d_name));
95 }
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 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 #ifdef WIN32
121 WalkDirectoryTreeSub(Dir, pWalker);
122 #else
123 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 #endif
135 }
136
137 #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
143 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 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 }
178 #endif
179 }

  ViewVC Help
Powered by ViewVC