svcore  1.9
PluginXml.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2006 Chris Cannam.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #include "PluginXml.h"
17 
18 #include <QRegExp>
19 #include <QXmlAttributes>
20 
21 #include <QDomDocument>
22 #include <QDomElement>
23 #include <QDomNamedNodeMap>
24 #include <QDomAttr>
25 
26 #include <QTextStream>
27 
28 #include <vamp-hostsdk/PluginBase.h>
29 #include "RealTimePluginInstance.h"
30 
31 #include <iostream>
32 
33 PluginXml::PluginXml(Vamp::PluginBase *plugin) :
34  m_plugin(plugin)
35 {
36 }
37 
39 
40 QString
42 {
43  QString rv(text);
44  rv.replace(";", "[[SEMICOLON]]");
45  rv.replace("=", "[[EQUALS]]");
46  return rv;
47 }
48 
49 QString
51 {
52  QString rv(text);
53  rv.replace("[[SEMICOLON]]", ";");
54  rv.replace("[[EQUALS]]", "=");
55  return rv;
56 }
57 
58 void
59 PluginXml::toXml(QTextStream &stream,
60  QString indent, QString extraAttributes) const
61 {
62  stream << indent;
63 
64  stream << QString("<plugin identifier=\"%1\" name=\"%2\" description=\"%3\" maker=\"%4\" version=\"%5\" copyright=\"%6\" %7 ")
65  .arg(encodeEntities(QString(m_plugin->getIdentifier().c_str())))
66  .arg(encodeEntities(QString(m_plugin->getName().c_str())))
67  .arg(encodeEntities(QString(m_plugin->getDescription().c_str())))
68  .arg(encodeEntities(QString(m_plugin->getMaker().c_str())))
69  .arg(m_plugin->getPluginVersion())
70  .arg(encodeEntities(QString(m_plugin->getCopyright().c_str())))
71  .arg(extraAttributes);
72 
73  if (!m_plugin->getPrograms().empty()) {
74  stream << QString("program=\"%1\" ")
75  .arg(encodeEntities(m_plugin->getCurrentProgram().c_str()));
76  }
77 
78  Vamp::PluginBase::ParameterList parameters =
79  m_plugin->getParameterDescriptors();
80 
81  for (Vamp::PluginBase::ParameterList::const_iterator i = parameters.begin();
82  i != parameters.end(); ++i) {
83 
84 // SVDEBUG << "PluginXml::toXml: parameter name \""
85 // << i->name.c_str() << "\" has value "
86 // << m_plugin->getParameter(i->name) << endl;
87 
88  stream << QString("param-%1=\"%2\" ")
89  .arg(stripInvalidParameterNameCharacters(QString(i->identifier.c_str())))
90  .arg(m_plugin->getParameter(i->identifier));
91  }
92 
94  dynamic_cast<RealTimePluginInstance *>(m_plugin);
95  if (rtpi) {
96  std::map<std::string, std::string> configurePairs =
97  rtpi->getConfigurePairs();
98  QString config;
99  for (std::map<std::string, std::string>::iterator i = configurePairs.begin();
100  i != configurePairs.end(); ++i) {
101  QString key = i->first.c_str();
102  QString value = i->second.c_str();
103  key = encodeConfigurationChars(key);
104  value = encodeConfigurationChars(value);
105  if (config != "") config += ";";
106  config += QString("%1=%2").arg(key).arg(value);
107  }
108  if (config != "") {
109  stream << QString("configuration=\"%1\" ")
110  .arg(encodeEntities(config));
111  }
112  }
113 
114  stream << "/>\n";
115 }
116 
117 #define CHECK_ATTRIBUTE(ATTRIBUTE, ACCESSOR) \
118  QString ATTRIBUTE = attrs.value(#ATTRIBUTE); \
119  if (ATTRIBUTE != "" && ATTRIBUTE != ACCESSOR().c_str()) { \
120  cerr << "WARNING: PluginXml::setParameters: Plugin " \
121  << #ATTRIBUTE << " does not match (attributes have \"" \
122  << ATTRIBUTE << "\", my " \
123  << #ATTRIBUTE << " is \"" << ACCESSOR() << "\")" << endl; \
124  }
125 
126 void
127 PluginXml::setParameters(const QXmlAttributes &attrs)
128 {
129  CHECK_ATTRIBUTE(identifier, m_plugin->getIdentifier);
130  CHECK_ATTRIBUTE(name, m_plugin->getName);
131  CHECK_ATTRIBUTE(description, m_plugin->getDescription);
132  CHECK_ATTRIBUTE(maker, m_plugin->getMaker);
133  CHECK_ATTRIBUTE(copyright, m_plugin->getCopyright);
134 
135  bool ok;
136  int version = attrs.value("version").trimmed().toInt(&ok);
137  if (ok && version != m_plugin->getPluginVersion()) {
138  cerr << "WARNING: PluginXml::setParameters: Plugin version does not match (attributes have " << version << ", my version is " << m_plugin->getPluginVersion() << ")" << endl;
139  }
140 
141  RealTimePluginInstance *rtpi =
142  dynamic_cast<RealTimePluginInstance *>(m_plugin);
143  if (rtpi) {
144  QString config = attrs.value("configuration");
145  if (config != "") {
146  QStringList configList = config.split(";");
147  for (QStringList::iterator i = configList.begin();
148  i != configList.end(); ++i) {
149  QStringList kv = i->split("=");
150  if (kv.count() < 2) {
151  cerr << "WARNING: PluginXml::setParameters: Malformed configure pair string: \"" << *i << "\"" << endl;
152  continue;
153  }
154  QString key(kv[0]), value(kv[1]);
155  key = decodeConfigurationChars(key);
156  value = decodeConfigurationChars(value);
157  rtpi->configure(key.toStdString(), value.toStdString());
158  }
159  }
160  }
161 
162  if (!m_plugin->getPrograms().empty()) {
163  m_plugin->selectProgram(attrs.value("program").toStdString());
164  }
165 
166  Vamp::PluginBase::ParameterList parameters =
167  m_plugin->getParameterDescriptors();
168 
169  for (Vamp::PluginBase::ParameterList::const_iterator i =
170  parameters.begin(); i != parameters.end(); ++i) {
171 
172  QString pname = QString("param-%1")
174  (QString(i->identifier.c_str())));
175 
176  if (attrs.value(pname) == "") {
177 // SVDEBUG << "PluginXml::setParameters: no parameter \"" << i->name << "\" (attribute \"" << name << "\")" << endl;
178  continue;
179  }
180 
181  bool ok;
182  float value = attrs.value(pname).trimmed().toFloat(&ok);
183  if (ok) {
184 // SVDEBUG << "PluginXml::setParameters: setting parameter \""
185 // << i->identifier << "\" to value " << value << endl;
186  m_plugin->setParameter(i->identifier, value);
187  } else {
188  cerr << "WARNING: PluginXml::setParameters: Invalid value \"" << attrs.value(pname) << "\" for parameter \"" << i->identifier << "\" (attribute \"" << pname << "\")" << endl;
189  }
190  }
191 }
192 
193 void
195 {
196  QDomDocument doc;
197 
198  QString error;
199  int errorLine;
200  int errorColumn;
201 
202 // SVDEBUG << "PluginXml::setParametersFromXml: XML is \""
203 // << xml << "\"" << endl;
204 
205  if (!doc.setContent(xml, false, &error, &errorLine, &errorColumn)) {
206  cerr << "PluginXml::setParametersFromXml: Error in parsing XML: " << error << " at line " << errorLine << ", column " << errorColumn << endl;
207  cerr << "Input follows:" << endl;
208  cerr << xml << endl;
209  cerr << "Input ends." << endl;
210  return;
211  }
212 
213  QDomElement pluginElt = doc.firstChildElement("plugin");
214  QDomNamedNodeMap attrNodes = pluginElt.attributes();
215  QXmlAttributes attrs;
216 
217  for (int i = 0; i < attrNodes.length(); ++i) {
218  QDomAttr attr = attrNodes.item(i).toAttr();
219  if (attr.isNull()) continue;
220 // SVDEBUG << "PluginXml::setParametersFromXml: Adding attribute \"" << attr.name()// << "\" with value \"" << attr.value() << "\"" << endl;
221  attrs.append(attr.name(), "", "", attr.value());
222  }
223 
224  setParameters(attrs);
225 }
226 
227 QString
229 {
230  s.replace(QRegExp("[^a-zA-Z0-9_]*"), "");
231  return s;
232 }
233 
virtual std::string configure(std::string, std::string)
virtual void setParametersFromXml(QString xml)
Set the parameters and program of a plugin from an XML plugin element as returned by toXml.
Definition: PluginXml.cpp:194
Vamp::PluginBase * m_plugin
Definition: PluginXml.h:56
static QString encodeEntities(QString)
PluginXml(Vamp::PluginBase *plugin)
Definition: PluginXml.cpp:33
virtual void setParameters(const QXmlAttributes &)
Set the parameters and program of a plugin from a set of XML attributes.
Definition: PluginXml.cpp:127
virtual ~PluginXml()
Definition: PluginXml.cpp:38
#define CHECK_ATTRIBUTE(ATTRIBUTE, ACCESSOR)
Definition: PluginXml.cpp:117
virtual ConfigurationPairMap getConfigurePairs()
virtual void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
Export plugin settings to XML.
Definition: PluginXml.cpp:59
static QString decodeConfigurationChars(QString text)
Definition: PluginXml.cpp:50
static QString encodeConfigurationChars(QString text)
Definition: PluginXml.cpp:41
QString stripInvalidParameterNameCharacters(QString) const
Definition: PluginXml.cpp:228