comparison src/vamp-hostsdk/Files.cpp @ 419:55de53d7c777

Merge
author Chris Cannam
date Tue, 01 Mar 2016 12:21:23 +0000
parents b7268e8bd292
children 35fa4733bc5d
comparison
equal deleted inserted replaced
418:a13635e9c440 419:55de53d7c777
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Vamp
5
6 An API for audio analysis and feature extraction plugins.
7
8 Centre for Digital Music, Queen Mary, University of London.
9 Copyright 2006-2015 Chris Cannam and QMUL.
10
11 Permission is hereby granted, free of charge, to any person
12 obtaining a copy of this software and associated documentation
13 files (the "Software"), to deal in the Software without
14 restriction, including without limitation the rights to use, copy,
15 modify, merge, publish, distribute, sublicense, and/or sell copies
16 of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 Except as contained in this notice, the names of the Centre for
31 Digital Music; Queen Mary, University of London; and Chris Cannam
32 shall not be used in advertising or otherwise to promote the sale,
33 use or other dealings in this Software without prior written
34 authorization.
35 */
36
37 #include <vamp-hostsdk/PluginHostAdapter.h>
38
39 #include "Files.h"
40
41 #include <cctype> // tolower
42
43 #include <cstring>
44
45 #ifdef _WIN32
46
47 #include <windows.h>
48 #include <tchar.h>
49 #define PLUGIN_SUFFIX "dll"
50
51 #else /* ! _WIN32 */
52
53 #include <dirent.h>
54 #include <dlfcn.h>
55
56 #ifdef __APPLE__
57 #define PLUGIN_SUFFIX "dylib"
58 #else /* ! __APPLE__ */
59 #define PLUGIN_SUFFIX "so"
60 #endif /* ! __APPLE__ */
61
62 #endif /* ! _WIN32 */
63
64 using namespace std;
65
66 vector<string>
67 Files::listLibraryFiles()
68 {
69 return listLibraryFilesMatching("");
70 }
71
72 vector<string>
73 Files::listLibraryFilesMatching(string libraryName)
74 {
75 vector<string> path = Vamp::PluginHostAdapter::getPluginPath();
76 vector<string> libraryFiles;
77
78 // we match case-insensitively
79 for (size_t i = 0; i < libraryName.length(); ++i) {
80 libraryName[i] = tolower(libraryName[i]);
81 }
82
83 for (size_t i = 0; i < path.size(); ++i) {
84
85 vector<string> files = listFiles(path[i], PLUGIN_SUFFIX);
86
87 for (vector<string>::iterator fi = files.begin();
88 fi != files.end(); ++fi) {
89
90 if (libraryName != "") {
91 // we match case-insensitively
92 string temp = *fi;
93 for (size_t i = 0; i < temp.length(); ++i) {
94 temp[i] = tolower(temp[i]);
95 }
96 // libraryName should be lacking an extension, as it
97 // is supposed to have come from the plugin key
98 string::size_type pi = temp.find('.');
99 if (pi == string::npos) {
100 if (libraryName != temp) continue;
101 } else {
102 if (libraryName != temp.substr(0, pi)) continue;
103 }
104 }
105
106 string fullPath = path[i];
107 fullPath = splicePath(fullPath, *fi);
108 libraryFiles.push_back(fullPath);
109 }
110 }
111
112 return libraryFiles;
113 }
114
115 void *
116 Files::loadLibrary(string path)
117 {
118 void *handle = 0;
119 #ifdef _WIN32
120 #ifdef UNICODE
121 int len = path.length() + 1; // cannot be more wchars than length in bytes of utf8 string
122 wchar_t *buffer = new wchar_t[len];
123 int rv = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), len, buffer, len);
124 if (rv <= 0) {
125 cerr << "Vamp::HostExt: Unable to convert library path \""
126 << path << "\" to wide characters " << endl;
127 delete[] buffer;
128 return handle;
129 }
130 handle = LoadLibrary(buffer);
131 delete[] buffer;
132 #else
133 handle = LoadLibrary(path.c_str());
134 #endif
135 if (!handle) {
136 cerr << "Vamp::HostExt: Unable to load library \""
137 << path << "\"" << endl;
138 }
139 #else
140 handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
141 if (!handle) {
142 cerr << "Vamp::HostExt: Unable to load library \""
143 << path << "\": " << dlerror() << endl;
144 }
145 #endif
146 return handle;
147 }
148
149 void
150 Files::unloadLibrary(void *handle)
151 {
152 #ifdef _WIN32
153 FreeLibrary((HINSTANCE)handle);
154 #else
155 dlclose(handle);
156 #endif
157 }
158
159 void *
160 Files::lookupInLibrary(void *handle, const char *symbol)
161 {
162 #ifdef _WIN32
163 return (void *)GetProcAddress((HINSTANCE)handle, symbol);
164 #else
165 return (void *)dlsym(handle, symbol);
166 #endif
167 }
168
169 string
170 Files::lcBasename(string path)
171 {
172 string basename(path);
173
174 string::size_type li = basename.rfind('/');
175 if (li != string::npos) basename = basename.substr(li + 1);
176
177 #ifdef _WIN32
178 li = basename.rfind('\\');
179 if (li != string::npos) basename = basename.substr(li + 1);
180 #endif
181
182 li = basename.find('.');
183 if (li != string::npos) basename = basename.substr(0, li);
184
185 for (size_t i = 0; i < basename.length(); ++i) {
186 basename[i] = tolower(basename[i]);
187 }
188
189 return basename;
190 }
191
192 string
193 Files::splicePath(string a, string b)
194 {
195 #ifdef _WIN32
196 return a + "\\" + b;
197 #else
198 return a + "/" + b;
199 #endif
200 }
201
202 vector<string>
203 Files::listFiles(string dir, string extension)
204 {
205 vector<string> files;
206
207 #ifdef _WIN32
208 string expression = dir + "\\*." + extension;
209 #ifdef UNICODE
210 int len = expression.length() + 1; // cannot be more wchars than length in bytes of utf8 string
211 wchar_t *buffer = new wchar_t[len];
212 int rv = MultiByteToWideChar(CP_UTF8, 0, expression.c_str(), len, buffer, len);
213 if (rv <= 0) {
214 cerr << "Vamp::HostExt: Unable to convert wildcard path \""
215 << expression << "\" to wide characters" << endl;
216 delete[] buffer;
217 return files;
218 }
219 WIN32_FIND_DATA data;
220 HANDLE fh = FindFirstFile(buffer, &data);
221 if (fh == INVALID_HANDLE_VALUE) {
222 delete[] buffer;
223 return files;
224 }
225
226 bool ok = true;
227 while (ok) {
228 wchar_t *fn = data.cFileName;
229 int wlen = wcslen(fn) + 1;
230 int maxlen = wlen * 6;
231 char *conv = new char[maxlen];
232 int rv = WideCharToMultiByte(CP_UTF8, 0, fn, wlen, conv, maxlen, 0, 0);
233 if (rv > 0) {
234 files.push_back(conv);
235 }
236 delete[] conv;
237 ok = FindNextFile(fh, &data);
238 }
239
240 FindClose(fh);
241 delete[] buffer;
242 #else
243 WIN32_FIND_DATA data;
244 HANDLE fh = FindFirstFile(expression.c_str(), &data);
245 if (fh == INVALID_HANDLE_VALUE) return files;
246
247 bool ok = true;
248 while (ok) {
249 files.push_back(data.cFileName);
250 ok = FindNextFile(fh, &data);
251 }
252
253 FindClose(fh);
254 #endif
255 #else
256
257 size_t extlen = extension.length();
258 DIR *d = opendir(dir.c_str());
259 if (!d) return files;
260
261 struct dirent *e = 0;
262 while ((e = readdir(d))) {
263
264 size_t len = strlen(e->d_name);
265 if (len < extlen + 2 ||
266 e->d_name + len - extlen - 1 != "." + extension) {
267 continue;
268 }
269
270 files.push_back(e->d_name);
271 }
272
273 closedir(d);
274 #endif
275
276 return files;
277 }