/[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 3082 - (show annotations) (download)
Mon Jan 9 18:39:35 2017 UTC (7 years, 3 months ago) by schoenebeck
File size: 6614 byte(s)
* Added support for sfz extension opcode 'script' which may be used to
  load real-time instrument script file (NKSP script language).
* Removed code duplication in SFZ file loading code.
* Bumped version (2.0.0.svn37).

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

  ViewVC Help
Powered by ViewVC