Files
salmanoff/commonLibs/lcameraDev/selectorParse.cpp
T

122 lines
2.6 KiB
C++

#include <selectorParse.h>
#include <stdexcept>
#include <cctype>
namespace lcamera_dev {
namespace {
SelectorCriterionKind parseCriterionKind(const std::string& prefixToken)
{
if (prefixToken == "lcamera-id") {
return SelectorCriterionKind::LibcameraId;
}
if (prefixToken == "index") {
return SelectorCriterionKind::Index;
}
if (prefixToken == "model-substr") {
return SelectorCriterionKind::ModelSubstr;
}
if (prefixToken == "model") {
return SelectorCriterionKind::Model;
}
if (prefixToken == "location") {
return SelectorCriterionKind::Location;
}
throw std::runtime_error(
"Unknown deviceSelector prefix: " + prefixToken);
}
SelectorCriterion parseCriterionClause(const std::string& clause)
{
const std::string trimmedClause = trimWhitespace(clause);
if (trimmedClause.empty()) {
throw std::runtime_error("Empty deviceSelector clause");
}
const size_t colonPos = trimmedClause.find(':');
if (colonPos == std::string::npos)
{
return SelectorCriterion{
SelectorCriterionKind::LibcameraId,
trimmedClause
};
}
const std::string prefixToken = trimWhitespace(
trimmedClause.substr(0, colonPos));
const std::string value = trimWhitespace(
trimmedClause.substr(colonPos + 1));
if (value.empty())
{
throw std::runtime_error(
"deviceSelector clause has empty value for prefix "
+ prefixToken);
}
return SelectorCriterion{
parseCriterionKind(prefixToken),
value
};
}
} // namespace
std::string trimWhitespace(const std::string& text)
{
size_t start = 0;
while (start < text.size() && std::isspace(static_cast<unsigned char>(text[start]))) {
++start;
}
size_t end = text.size();
while (end > start
&& std::isspace(static_cast<unsigned char>(text[end - 1])))
{
--end;
}
return text.substr(start, end - start);
}
std::vector<SelectorCriterion> parseDeviceSelector(
const std::string& deviceSelector)
{
const std::string trimmedSelector = trimWhitespace(deviceSelector);
if (trimmedSelector.empty()) {
throw std::runtime_error("deviceSelector is empty");
}
std::vector<SelectorCriterion> criteria;
std::string currentClause;
currentClause.reserve(trimmedSelector.size());
for (size_t i = 0; i < trimmedSelector.size(); ++i)
{
const char ch = trimmedSelector[i];
if (ch == '\\' && i + 1 < trimmedSelector.size()
&& trimmedSelector[i + 1] == ';')
{
currentClause.push_back(';');
++i;
continue;
}
if (ch == ';')
{
criteria.push_back(parseCriterionClause(currentClause));
currentClause.clear();
continue;
}
currentClause.push_back(ch);
}
criteria.push_back(parseCriterionClause(currentClause));
return criteria;
}
} // namespace lcamera_dev