Mercurial > hg > vamp-plugin-sdk
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 } |