comparison vamp-hostsdk/PluginLoader.cpp @ 57:09a1aac6c362 host-factory-stuff

* add wrapper base * make loader able to look up categories
author cannam
date Wed, 09 May 2007 15:21:37 +0000
parents 4ab6224110ef
children
comparison
equal deleted inserted replaced
56:4ab6224110ef 57:09a1aac6c362
37 #include "PluginLoader.h" 37 #include "PluginLoader.h"
38 #include "PluginHostAdapter.h" 38 #include "PluginHostAdapter.h"
39 39
40 #include "system.h" 40 #include "system.h"
41 41
42 #include <fstream>
43
42 #include <dirent.h> // POSIX directory open and read 44 #include <dirent.h> // POSIX directory open and read
45
46 using namespace std;
43 47
44 namespace Vamp { 48 namespace Vamp {
45 49
46 PluginLoader::PluginLoader() 50 PluginLoader::PluginLoader()
47 { 51 {
49 53
50 PluginLoader::~PluginLoader() 54 PluginLoader::~PluginLoader()
51 { 55 {
52 } 56 }
53 57
54 std::vector<PluginLoader::PluginKey> 58 vector<PluginLoader::PluginKey>
55 PluginLoader::listPlugins() 59 PluginLoader::listPlugins()
56 { 60 {
57 if (m_pluginLibraryMap.empty()) { 61 if (m_pluginLibraryMap.empty()) {
58 62
59 std::vector<std::string> path = PluginHostAdapter::getPluginPath(); 63 vector<string> path = PluginHostAdapter::getPluginPath();
60 64
61 size_t suffixLen = strlen(PLUGIN_SUFFIX); 65 size_t suffixLen = strlen(PLUGIN_SUFFIX);
62 66
63 for (size_t i = 0; i < path.size(); ++i) { 67 for (size_t i = 0; i < path.size(); ++i) {
64
65 DIR *d = opendir(path[i].c_str());
66 if (!d) {
67 // perror("Failed to open directory");
68 continue;
69 }
70 68
71 struct dirent *e = 0; 69 vector<string> files = getFilesInDir(path[i], PLUGIN_SUFFIX);
72 while ((e = readdir(d))) { 70
73 71
74 if (!(e->d_type & DT_REG) || !e->d_name) { 72 for (vector<string>::iterator fi = files.begin();
75 continue; 73 fi != files.end(); ++fi) {
76 } 74
77 75 string basename = *fi;
78 int len = strlen(e->d_name);
79 if (len < int(suffixLen + 2) ||
80 e->d_name[len - suffixLen - 1] != '.' ||
81 strcmp(e->d_name + len - suffixLen, PLUGIN_SUFFIX)) {
82 continue;
83 }
84
85 std::string basename = e->d_name;
86 basename = basename.substr(0, basename.length() - suffixLen - 1); 76 basename = basename.substr(0, basename.length() - suffixLen - 1);
87 std::string fullPath = path[i].c_str(); 77
88 fullPath = fullPath + "/" + e->d_name; 78 string fullPath = path[i];
79 fullPath = fullPath + "/" + *fi; //!!! systemize
89 void *handle = DLOPEN(fullPath, RTLD_LAZY); 80 void *handle = DLOPEN(fullPath, RTLD_LAZY);
90 81
91 if (!handle) { 82 if (!handle) {
92 std::cerr << "Vamp::PluginLoader: " << e->d_name 83 cerr << "Vamp::PluginLoader: " << *fi
93 << ": unable to load library (" << DLERROR() 84 << ": unable to load library (" << DLERROR()
94 << ")" << std::endl; 85 << ")" << endl;
95 continue; 86 continue;
96 } 87 }
97 88
98 VampGetPluginDescriptorFunction fn = 89 VampGetPluginDescriptorFunction fn =
99 (VampGetPluginDescriptorFunction)DLSYM 90 (VampGetPluginDescriptorFunction)DLSYM
116 ++index; 107 ++index;
117 } 108 }
118 109
119 DLCLOSE(handle); 110 DLCLOSE(handle);
120 } 111 }
121 112 }
122 closedir(d); 113 }
123 } 114
124 } 115 vector<PluginKey> plugins;
125 116 for (map<PluginKey, string>::iterator mi =
126 std::vector<PluginKey> plugins;
127 for (std::map<PluginKey, std::string>::iterator mi =
128 m_pluginLibraryMap.begin(); 117 m_pluginLibraryMap.begin();
129 mi != m_pluginLibraryMap.end(); ++mi) { 118 mi != m_pluginLibraryMap.end(); ++mi) {
130 plugins.push_back(mi->first); 119 plugins.push_back(mi->first);
131 } 120 }
132 121
133 return plugins; 122 return plugins;
134 } 123 }
135 124
136 std::string 125 PluginLoader::PluginCategoryHierarchy
137 PluginLoader::getLibraryPath(PluginKey key) 126 PluginLoader::getPluginCategory(PluginKey plugin)
127 {
128 if (m_taxonomy.empty()) generateTaxonomy();
129 if (m_taxonomy.find(plugin) == m_taxonomy.end()) return PluginCategoryHierarchy();
130 return m_taxonomy[plugin];
131 }
132
133 string
134 PluginLoader::getLibraryPathForPlugin(PluginKey plugin)
138 { 135 {
139 if (m_pluginLibraryMap.empty()) (void)listPlugins(); 136 if (m_pluginLibraryMap.empty()) (void)listPlugins();
140 if (m_pluginLibraryMap.find(key) == m_pluginLibraryMap.end()) return ""; 137 if (m_pluginLibraryMap.find(plugin) == m_pluginLibraryMap.end()) return "";
141 return m_pluginLibraryMap[key]; 138 return m_pluginLibraryMap[plugin];
142 } 139 }
143 140
144 Plugin * 141 Plugin *
145 PluginLoader::load(PluginKey key, float inputSampleRate) 142 PluginLoader::load(PluginKey key, float inputSampleRate)
146 { 143 {
147 std::string fullPath = getLibraryPath(key); 144 string fullPath = getLibraryPathForPlugin(key);
148 if (fullPath == "") return 0; 145 if (fullPath == "") return 0;
149 146
150 std::string::size_type ki = key.find(':'); 147 string::size_type ki = key.find(':');
151 if (ki == std::string::npos) { 148 if (ki == string::npos) {
152 //!!! flag error 149 //!!! flag error
153 return 0; 150 return 0;
154 } 151 }
155 152
156 std::string identifier = key.substr(ki + 1); 153 string identifier = key.substr(ki + 1);
157 154
158 void *handle = DLOPEN(fullPath, RTLD_LAZY); 155 void *handle = DLOPEN(fullPath, RTLD_LAZY);
159 156
160 if (!handle) { 157 if (!handle) {
161 std::cerr << "Vamp::PluginLoader: " << fullPath 158 cerr << "Vamp::PluginLoader: " << fullPath
162 << ": unable to load library (" << DLERROR() 159 << ": unable to load library (" << DLERROR()
163 << ")" << std::endl; 160 << ")" << endl;
164 return 0; 161 return 0;
165 } 162 }
166 163
167 VampGetPluginDescriptorFunction fn = 164 VampGetPluginDescriptorFunction fn =
168 (VampGetPluginDescriptorFunction)DLSYM 165 (VampGetPluginDescriptorFunction)DLSYM
177 174
178 int index = 0; 175 int index = 0;
179 const VampPluginDescriptor *descriptor = 0; 176 const VampPluginDescriptor *descriptor = 0;
180 177
181 while ((descriptor = fn(VAMP_API_VERSION, index))) { 178 while ((descriptor = fn(VAMP_API_VERSION, index))) {
182 if (std::string(descriptor->identifier) == identifier) { 179 if (string(descriptor->identifier) == identifier) {
183 return new Vamp::PluginHostAdapter(descriptor, inputSampleRate); 180 return new Vamp::PluginHostAdapter(descriptor, inputSampleRate);
184 } 181 }
185 ++index; 182 ++index;
186 } 183 }
187 184
188 //!!! flag error 185 //!!! flag error
189 return 0; 186 return 0;
190 } 187 }
191 188
192 } 189 vector<string>
193 190 PluginLoader::getFilesInDir(string dir, string extension)
191 {
192 vector<string> files;
193
194 DIR *d = opendir(dir.c_str());
195 if (!d) return files;
196
197 struct dirent *e = 0;
198 while ((e = readdir(d))) {
199
200 if (!(e->d_type & DT_REG) || !e->d_name) {
201 continue;
202 }
203
204 int len = strlen(e->d_name);
205 if (len < int(extension.length() + 2) ||
206 e->d_name[len - extension.length() - 1] != '.' ||
207 strcmp(e->d_name + len - extension.length(), extension.c_str())) {
208 continue;
209 }
210
211 files.push_back(e->d_name);
212 }
213
214 closedir(d);
215
216 return files;
217 }
218
219 void
220 PluginLoader::generateTaxonomy()
221 {
222 // cerr << "PluginLoader::generateTaxonomy" << endl;
223
224 vector<string> path = PluginHostAdapter::getPluginPath();
225 string libfragment = "/lib/";
226 vector<string> catpath;
227
228 string suffix = "cat";
229
230 for (vector<string>::iterator i = path.begin();
231 i != path.end(); ++i) {
232
233 string dir = *i;
234 string::size_type li = dir.find(libfragment);
235
236 if (li != string::npos) {
237 catpath.push_back
238 (dir.substr(0, li)
239 + "/share/"
240 + dir.substr(li + libfragment.length()));
241 }
242
243 catpath.push_back(dir);
244 }
245
246 char buffer[1024];
247
248 for (vector<string>::iterator i = catpath.begin();
249 i != catpath.end(); ++i) {
250
251 vector<string> files = getFilesInDir(*i, suffix);
252
253 for (vector<string>::iterator fi = files.begin();
254 fi != files.end(); ++fi) {
255
256 string filepath = *i + "/" + *fi; //!!! systemize
257 ifstream is(filepath.c_str(), ifstream::in | ifstream::binary);
258
259 if (is.fail()) {
260 // cerr << "failed to open: " << filepath << endl;
261 continue;
262 }
263
264 // cerr << "opened: " << filepath << endl;
265
266 while (!!is.getline(buffer, 1024)) {
267
268 string line(buffer);
269
270 // cerr << "line = " << line << endl;
271
272 string::size_type di = line.find("::");
273 if (di == string::npos) continue;
274
275 string id = line.substr(0, di);
276 string encodedCat = line.substr(di + 2);
277
278 if (id.substr(0, 5) != "vamp:") continue;
279 id = id.substr(5);
280
281 while (encodedCat.length() >= 1 &&
282 encodedCat[encodedCat.length()-1] == '\r') {
283 encodedCat = encodedCat.substr(0, encodedCat.length()-1);
284 }
285
286 // cerr << "id = " << id << ", cat = " << encodedCat << endl;
287
288 PluginCategoryHierarchy category;
289 string::size_type ai;
290 while ((ai = encodedCat.find(" > ")) != string::npos) {
291 category.push_back(encodedCat.substr(0, ai));
292 encodedCat = encodedCat.substr(ai + 3);
293 }
294 if (encodedCat != "") category.push_back(encodedCat);
295
296 m_taxonomy[id] = category;
297 }
298 }
299 }
300 }
301
302
303 }