56 StatusCode make_string_token (
const std::string& input,
57 std::string::size_type&
pos,
60 using namespace asg::msgProperty;
62 token.
m_type = TokenType::STRING;
68 return StatusCode::FAILURE;
74 if (input[
pos] ==
'\\')
80 return StatusCode::FAILURE;
82 if (input[
pos] ==
'\'' || input[
pos] ==
'"' ||
83 input[
pos] ==
'\\' || input[
pos] ==
',')
88 ANA_MSG_ERROR (
"invalid character '" << input[
pos] <<
"' at position " <<
pos <<
" of string: " << input);
89 return StatusCode::FAILURE;
101 return StatusCode::FAILURE;
104 return StatusCode::SUCCESS;
107 StatusCode make_number_token (
const std::string& input,
108 std::string::size_type&
pos,
111 token.
m_type = TokenType::NUMBER;
114 (isalnum (input[
pos]) || input[
pos] ==
'.' ||
115 input[
pos] ==
'+' || input[
pos] ==
'-'); ++
pos)
116 token.m_cooked = input[
pos];
117 return StatusCode::SUCCESS;
120 StatusCode make_space_token (
const std::string& input,
121 std::string::size_type&
pos,
127 token.m_cooked = input[
pos];
128 return StatusCode::SUCCESS;
131 StatusCode make_char_token (
const std::string& input,
132 std::string::size_type&
pos,
135 using namespace asg::msgProperty;
137 if (input[
pos] ==
'[')
138 token.
m_type = TokenType::LIST_OPEN;
139 else if (input[
pos] ==
']')
140 token.
m_type = TokenType::LIST_CLOSE;
141 else if (input[
pos] ==
',')
142 token.
m_type = TokenType::COMMA;
143 else if (input[
pos] ==
'{')
144 token.
m_type = TokenType::MAP_OPEN;
145 else if (input[
pos] ==
'}')
146 token.
m_type = TokenType::MAP_CLOSE;
147 else if (input[
pos] ==
':')
148 token.
m_type = TokenType::MAP_SEPARATOR;
151 ANA_MSG_ERROR (
"unexpected token '" << input[
pos] <<
"' at position" <<
pos <<
" of string: " << input);
152 return StatusCode::FAILURE;
155 return StatusCode::SUCCESS;
158 StatusCode make_token_list (
const std::string& input,
159 std::vector<Token>&
tokens)
161 using namespace asg::msgProperty;
164 for (std::string::size_type
start = 0,
pos = 0;
168 if (input[
pos] ==
'\'' || input[
pos] ==
'"')
171 }
else if (isdigit (input[
pos]))
174 }
else if (isspace (input[
pos]))
181 token.m_raw = std::string_view (input).substr (
start,
pos -
start);
182 tokens.push_back (std::move (token));
184 return StatusCode::SUCCESS;
191 std::vector<Token>&
result,
194 using namespace asg::msgProperty;
204 case TokenType::STRING:
205 case TokenType::NUMBER:
206 case TokenType::COMMA:
207 case TokenType::MAP_SEPARATOR:
208 case TokenType::SUBGROUP:
212 case TokenType::LIST_OPEN:
213 case TokenType::MAP_OPEN:
216 subtoken.
m_type = TokenType::SUBGROUP;
217 subtoken.m_subtokens.emplace_back (std::move (*
iterator));
219 if (make_token_tree (
iterator,
end, subtoken.m_subtokens,
true).isFailure())
220 return StatusCode::FAILURE;
222 subtoken.m_raw = std::string_view (subtoken.m_subtokens.front().m_raw.data(), subtoken.m_subtokens.back().m_raw.end() - subtoken.m_subtokens.front().m_raw.begin());
223 result.emplace_back (std::move (subtoken));
226 case TokenType::LIST_CLOSE:
227 case TokenType::MAP_CLOSE:
231 return StatusCode::FAILURE;
235 if ((
result.back().m_type == TokenType::LIST_CLOSE &&
236 result.front().m_type != TokenType::LIST_OPEN) ||
237 (
result.back().m_type == TokenType::MAP_CLOSE &&
238 result.front().m_type != TokenType::MAP_OPEN))
241 return StatusCode::FAILURE;
243 return StatusCode::SUCCESS;
249 return StatusCode::FAILURE;
251 return StatusCode::SUCCESS;
256 std::string quoteString (
const std::string& raw)
261 if (
ch ==
',' ||
ch ==
'\\' ||
ch ==
'"')
276 std::string myresult;
277 for (
const auto& subvalue :
value)
279 if (!myresult.empty())
281 myresult += quoteString (subvalue.first) +
":" + quoteString (subvalue.second);
283 result =
"{" + std::move (myresult) +
"}";
284 return StatusCode::SUCCESS;
292 std::string myresult;
293 for (
const auto& subvalue :
value)
295 if (!myresult.empty())
297 myresult += quoteString (subvalue);
299 result =
"[" + std::move (myresult) +
"]";
300 return StatusCode::SUCCESS;
308 if (
value.find (
"\\") == std::string::npos)
310 if (
value.find (
"\'") == std::string::npos)
313 return StatusCode::SUCCESS;
315 if (
value.find (
"\"") == std::string::npos)
318 return StatusCode::SUCCESS;
322 if (
value.find (
"\'") != std::string::npos &&
323 value.find (
"\"") == std::string::npos)
333 return StatusCode::SUCCESS;
342 using namespace asg::msgProperty;
345 if (
value.find (
'\'') == std::string::npos &&
346 value.find (
'"') == std::string::npos)
349 return StatusCode::SUCCESS;
352 std::vector<Token>
tokens;
368 return StatusCode::FAILURE;
373 return StatusCode::FAILURE;
376 return StatusCode::SUCCESS;
382 std::vector<std::string>&
result)
384 using namespace asg::msgProperty;
386 std::vector<std::string> myresult;
388 std::vector<Token>
tokens;
393 std::string subresult;
394 for (
auto& token :
tokens)
396 if (token.
m_type == TokenType::LIST_OPEN)
400 subresult += token.m_raw;
401 }
else if (
level == 0)
408 return StatusCode::FAILURE;
412 return StatusCode::FAILURE;
415 }
else switch (token.
m_type)
417 case TokenType::MAP_SEPARATOR:
418 case TokenType::MAP_OPEN:
419 case TokenType::MAP_CLOSE:
420 case TokenType::SUBGROUP:
423 ANA_MSG_ERROR (
"(currently) unsupported token in vector: " << token.m_raw);
424 return StatusCode::FAILURE;
427 case TokenType::STRING:
428 case TokenType::NUMBER:
429 if (!subresult.empty())
431 ANA_MSG_ERROR (
"invalid entry in vector: " << subresult << token.m_raw);
432 return StatusCode::FAILURE;
434 subresult = std::move (token.m_raw);
436 case TokenType::COMMA:
437 if (subresult.empty())
440 return StatusCode::FAILURE;
442 myresult.push_back (std::move (subresult));
445 case TokenType::LIST_OPEN:
449 return StatusCode::FAILURE;
452 case TokenType::LIST_CLOSE:
453 if (!subresult.empty())
455 myresult.push_back (std::move (subresult));
459 if (!myresult.empty())
462 return StatusCode::FAILURE;
468 if (token.
m_type == TokenType::LIST_CLOSE)
473 return StatusCode::FAILURE;
481 return StatusCode::FAILURE;
484 return StatusCode::SUCCESS;
490 std::map<std::string,std::string>&
result)
492 using namespace asg::msgProperty;
494 std::vector<Token> tokenTree;
496 std::vector<Token> tokenList;
502 if (tokenTree.size() != 1 ||
503 tokenTree[0].m_type != TokenType::SUBGROUP ||
504 tokenTree[0].m_subtokens[0].m_type != TokenType::MAP_OPEN)
507 return StatusCode::FAILURE;
512 for (std::size_t
index = 1;
513 index < tokenTree[0].m_subtokens.size()-1; ++
index)
515 Token& mytoken = tokenTree[0].m_subtokens[
index];
519 if (mytoken.m_type != TokenType::COMMA)
522 return StatusCode::FAILURE;
526 if (mytoken.m_type == TokenType::COMMA ||
527 mytoken.m_type == TokenType::MAP_SEPARATOR)
530 return StatusCode::FAILURE;
534 if (mytoken.m_type != TokenType::MAP_SEPARATOR)
537 return StatusCode::FAILURE;
541 if (mytoken.m_type == TokenType::COMMA ||
542 mytoken.m_type == TokenType::MAP_SEPARATOR)
545 return StatusCode::FAILURE;
547 Token& keytoken = tokenTree[0].m_subtokens[
index-2];
548 result.emplace (keytoken.m_raw, mytoken.m_raw);
553 tokenTree[0].m_subtokens.size()%4 != 1)
556 return StatusCode::FAILURE;
558 return StatusCode::SUCCESS;
571 if( ! this->pointer() ) {
575 std::string asString;
578 return this->setString (asString).isFailure();