Mantid
Loading...
Searching...
No Matches
ParseKeyValueString.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
9
10#include <QStringList>
11#include <boost/algorithm/string.hpp>
12#include <boost/numeric/conversion/cast.hpp>
13#include <boost/tokenizer.hpp>
14
15#include <vector>
16
18
19namespace {
20void appendKeyValuePair(const std::pair<std::string, std::string> &kvp, const bool quoteValues,
21 std::ostringstream &resultStream) {
22 if (quoteValues)
23 resultStream << kvp.first << "='" << kvp.second << '\'';
24 else
25 resultStream << kvp.first << "=" << kvp.second;
26}
27
34void trimQuotes(QString &value, const char quote, const char escape) {
35
36 // If size is less than 2, nothing to trim (we must have matching
37 // quotes at start/end)
38 if (value.size() < 2)
39 return;
40
41 // Must have matching start/end quotes to trim
42 if (value.startsWith(quote) && value.endsWith(quote)) {
43
44 // Check the final quote is not escaped by a backslash (the
45 // first character can't be an escape as we've already checked
46 // it's a quote mark)
47 if (value.size() < 3 || value.at(value.size() - 2) != escape) {
48 // Ok, trim it
49 value.remove(0, 1);
50 value.remove(value.size() - 1, 1);
51 }
52 }
53}
54} // unnamed namespace
55
62 // Remember original value
63 const auto valueIn = value;
64
65 // Trim whitespace
66 value = value.trimmed();
67
68 // Trim double/single quotes
69 trimQuotes(value, '"', '\\');
70 trimQuotes(value, '\'', '\\');
71
72 // If trimming was done, recurse to remove any nested quotes/whitespace
73 if (value.size() > 0 && value != valueIn)
75}
76
82void trimWhitespaceQuotesAndEmptyValues(QStringList &values) {
83 for (auto &value : values)
85
86 values.removeAll("");
87}
88
97std::map<std::string, std::string> parseKeyValueString(const std::string &str, const std::string &separator) {
98 /*
99 This is a bad example of using a tokenizer, and
100 Mantid::Kernel::StringTokenizer should
101 ideally be used for this (see LoadProcessedNexus, Fit1D or others for
102 examples)
103
104 The reason we must use boost::tokenizer here is that passing a list of
105 separators is not
106 yet possible with Mantid::Kernel::StringTokenizer.
107 */
108 boost::tokenizer<boost::escaped_list_separator<char>> tok(
109 str, boost::escaped_list_separator<char>("\\", separator, "\"'"));
110 std::map<std::string, std::string> kvp;
111
112 for (const auto &it : tok) {
113 std::vector<std::string> valVec;
114 boost::split(valVec, it, boost::is_any_of("="));
115
116 if (valVec.size() > 1) {
117 // We split on all '='s. The first delimits the key, the rest are assumed
118 // to be part of the value
119 std::string key = valVec[0];
120 // Drop the key from the values vector
121 valVec.begin() = valVec.erase(valVec.begin());
122 // Join the remaining sections,
123 std::string value = boost::algorithm::join(valVec, "=");
124
125 // Remove any unwanted whitespace
126 boost::trim(key);
127 boost::trim(value);
128
129 if (key.empty() || value.empty())
130 throw std::runtime_error("Invalid key value pair, '" + it + "'");
131
132 kvp[key] = value;
133 } else {
134 throw std::runtime_error("Invalid key value pair, '" + it + "'");
135 }
136 }
137 return kvp;
138}
139
148std::map<QString, QString> parseKeyValueQString(const QString &qstr, const std::string &separator) {
149 /*
150 This is a bad example of using a tokenizer, and
151 Mantid::Kernel::StringTokenizer should
152 ideally be used for this (see LoadProcessedNexus, Fit1D or others for
153 examples)
154
155 The reason we must use boost::tokenizer here is that passing a list of
156 separators is not
157 yet possible with Mantid::Kernel::StringTokenizer.
158 */
159 auto str = qstr.toStdString();
160 boost::tokenizer<boost::escaped_list_separator<char>> tok(
161 str, boost::escaped_list_separator<char>("\\", separator, "\"'"));
162 std::map<QString, QString> kvp;
163
164 for (const auto &it : tok) {
165 auto keyValueString = QString::fromStdString(it);
166 auto valVec = keyValueString.split("=");
167
168 if (valVec.size() > 1) {
169 // We split on all '='s. The first delimits the key, the rest are assumed
170 // to be part of the value
171 auto key = valVec[0].trimmed();
172 // Drop the key from the values vector
173 valVec.removeFirst();
174 // Join the remaining sections
175 auto value = valVec.join("=").trimmed();
176
177 if (key.isEmpty() || value.isEmpty())
178 throw std::runtime_error("Invalid key value pair, '" + it + "'");
179
180 kvp[key] = value;
181 } else {
182 throw std::runtime_error("Invalid key value pair, '" + it + "'");
183 }
184 }
185 return kvp;
186}
187
190QString convertMapToString(const std::map<QString, QString> &optionsMap, const char separator, const bool quoteValues) {
191 QString result;
192 bool first = true;
193
194 for (auto &kvp : optionsMap) {
195 if (kvp.second.isEmpty())
196 continue;
197
198 if (!first)
199 result += separator;
200 else
201 first = false;
202
203 const auto key = kvp.first;
204 auto value = kvp.second;
205
206 if (quoteValues)
207 value = "'" + value + "'";
208
209 result += key + "=" + value;
210 }
211
212 return result;
213}
214
217std::string convertMapToString(const std::map<std::string, std::string> &optionsMap, const char separator,
218 const bool quoteValues) {
219 std::string result;
220 bool first = true;
221
222 for (auto &kvp : optionsMap) {
223 if (kvp.second.empty())
224 continue;
225
226 if (!first)
227 result += separator;
228 else
229 first = false;
230
231 const auto key = kvp.first;
232 auto value = kvp.second;
233
234 if (quoteValues)
235 value = "'" + value + "'";
236
237 result += key + "=" + value;
238 }
239
240 return result;
241}
242
243std::string optionsToString(std::map<std::string, std::string> const &options, const bool quoteValues,
244 const std::string &separator) {
245 if (!options.empty()) {
246 std::ostringstream resultStream;
247 auto optionsKvpIt = options.cbegin();
248
249 auto const &firstKvp = (*optionsKvpIt);
250 appendKeyValuePair(firstKvp, quoteValues, resultStream);
251 ++optionsKvpIt;
252
253 for (; optionsKvpIt != options.cend(); ++optionsKvpIt) {
254 auto kvp = (*optionsKvpIt);
255 resultStream << separator;
256 appendKeyValuePair(kvp, quoteValues, resultStream);
257 }
258
259 return resultStream.str();
260 } else {
261 return std::string();
262 }
263}
264
266 auto props = options.getDeclaredPropertyNames();
267 if (props.empty()) {
268 return std::string();
269 }
270 auto result = std::string(props[0] + std::string("=") + options.getPropertyValue(props[0]));
271 return std::accumulate(++props.cbegin(), props.cend(), result, [&options](auto const &result, auto const &prop) {
272 return result + std::string(";") + prop + std::string("=") + options.getPropertyValue(prop);
273 });
274}
275
276QStringList stdVectorToQStringList(std::vector<std::string> const &vec) {
277 QStringList qStringList;
278 qStringList.reserve(static_cast<int>(vec.size()));
279 std::transform(vec.cbegin(), vec.cend(), std::back_inserter(qStringList),
280 [](std::string const &str) { return QString::fromStdString(str); });
281 return qStringList;
282}
283
284std::vector<std::string> qStringListToStdVector(QStringList const &qList) {
285 std::vector<std::string> vec;
286 vec.reserve(static_cast<std::size_t>(qList.size()));
287 std::transform(qList.cbegin(), qList.cend(), std::back_inserter(vec),
288 [](QString const &element) { return element.toStdString(); });
289 return vec;
290}
291
292std::vector<std::string> qListToStdVector(QList<std::string> const &qList) {
293 std::vector<std::string> vec;
294 vec.reserve(static_cast<std::size_t>(qList.size()));
295 std::transform(qList.cbegin(), qList.cend(), std::back_inserter(vec),
296 [](std::string const &element) { return element; });
297 return vec;
298}
299
300/*
301 * Converts a standard vector of standard strings to a QVector of QStrings.
302 *
303 * @param stringVec The standard vector of standard strings to convert.
304 * @return A QVector of QStrings.
305 */
306QVector<QString> convertStdStringVector(const std::vector<std::string> &stringVec) {
307 QVector<QString> resultVec;
308 resultVec.reserve(boost::numeric_cast<int>(stringVec.size()));
309 std::transform(stringVec.cbegin(), stringVec.cend(), std::back_inserter(resultVec),
310 [](const auto &str) { return QString::fromStdString(str); });
311 return resultVec;
312}
313
314} // namespace MantidQt::MantidWidgets
double value
The value of the point.
Definition FitMW.cpp:51
std::vector< T > const * vec
virtual std::vector< std::string > getDeclaredPropertyNames() const noexcept=0
Get the list of managed property names.
virtual std::string getPropertyValue(const std::string &name) const =0
Get the value of a property as a string.
QString EXPORT_OPT_MANTIDQT_COMMON convertMapToString(const std::map< QString, QString > &optionsMap, const char separator=',', const bool quoteValues=true)
Convert an options map to a string.
QStringList EXPORT_OPT_MANTIDQT_COMMON stdVectorToQStringList(std::vector< std::string > const &vec)
void trimWhitespaceQuotesAndEmptyValues(QStringList &values)
Trim whitespace and quotes from the start/end for all strings in the given list, and subsequently rem...
std::map< std::string, std::string > DLLExport parseKeyValueString(const std::string &str, const std::string &separator=",")
Parses a string in the format ‘a = 1,b=2, c = "1,2,3,4", d = 5.0, e='a,b,c’` into a map of key/value ...
std::map< QString, QString > DLLExport parseKeyValueQString(const QString &str, const std::string &separator=",")
Parses a string in the format ‘a = 1,b=2, c = "1,2,3,4", d = 5.0, e='a,b,c’` into a map of key/value ...
void trimWhitespaceAndQuotes(const QString &valueIn)
std::vector< std::string > EXPORT_OPT_MANTIDQT_COMMON qListToStdVector(QList< std::string > const &qList)
std::string EXPORT_OPT_MANTIDQT_COMMON optionsToString(std::map< std::string, std::string > const &options, const bool quoteValues=true, const std::string &separator=", ")
std::string EXPORT_OPT_MANTIDQT_COMMON convertAlgPropsToString(Mantid::API::IAlgorithmRuntimeProps const &options)
QVector< QString > EXPORT_OPT_MANTIDQT_COMMON convertStdStringVector(const std::vector< std::string > &stringVec)
std::vector< std::string > EXPORT_OPT_MANTIDQT_COMMON qStringListToStdVector(QStringList const &qList)