10#include <botan/internal/parsing.h>
12#include <botan/exceptn.h>
13#include <botan/internal/fmt.h>
14#include <botan/internal/loadstor.h>
23std::optional<size_t> digit_from_ascii(
char c) {
24 if(c >=
'0' && c <=
'9') {
31template <std::
unsigned_
integral T>
32std::optional<T> parse_decimal_integer(std::string_view input,
bool require_canonical) {
33 if(input.empty() || input.size() > (std::numeric_limits<T>::digits10 + 1)) {
38 if(require_canonical && input.size() > 1 && input.front() ==
'0') {
44 for(
const char c : input) {
45 if(
const auto digit = digit_from_ascii(c)) {
46 if(accum > (std::numeric_limits<T>::max() -
static_cast<T
>(*digit)) / 10) {
49 accum = accum * 10 +
static_cast<T
>(*digit);
60std::optional<uint16_t>
parse_u16(std::string_view input,
bool require_canonical) {
61 return parse_decimal_integer<uint16_t>(input, require_canonical);
64std::optional<uint32_t>
parse_u32(std::string_view input,
bool require_canonical) {
65 return parse_decimal_integer<uint32_t>(input, require_canonical);
68std::optional<uint64_t>
parse_u64(std::string_view input,
bool require_canonical) {
69 return parse_decimal_integer<uint64_t>(input, require_canonical);
72std::optional<size_t>
parse_sz(std::string_view input,
bool require_canonical) {
73 return parse_decimal_integer<size_t>(input, require_canonical);
77 if(
const auto parsed =
parse_u32(input)) {
88 if(scan_name.find(
'(') == std::string::npos && scan_name.find(
')') == std::string::npos) {
89 return {std::string(scan_name)};
92 std::string name(scan_name);
93 std::string substring;
94 std::vector<std::string> elems;
97 elems.push_back(name.substr(0, name.find(
'(')));
98 name = name.substr(name.find(
'('));
100 for(
auto i = name.begin(); i != name.end(); ++i) {
107 if(level == 1 && i == name.end() - 1) {
108 if(elems.size() == 1) {
109 elems.push_back(substring.substr(1));
111 elems.push_back(substring);
116 if(level == 0 || (level == 1 && i != name.end() - 1)) {
122 if(c ==
',' && level == 1) {
123 if(elems.size() == 1) {
124 elems.push_back(substring.substr(1));
126 elems.push_back(substring);
134 if(!substring.empty()) {
141std::vector<std::string>
split_on(std::string_view str,
char delim) {
142 std::vector<std::string> elems;
148 for(
const char c : str) {
150 if(!substr.empty()) {
151 elems.push_back(substr);
162 elems.push_back(substr);
170std::string
string_join(
const std::vector<std::string>& strs,
char delim) {
171 std::ostringstream out;
173 for(
size_t i = 0; i != strs.size(); ++i) {
186 std::string lower(str);
187 for(
char& c : lower) {
188 if(c >=
'A' && c <=
'Z') {
189 c =
static_cast<char>(c + (
'a' -
'A'));
std::optional< uint64_t > parse_u64(std::string_view input, bool require_canonical)
std::string fmt(std::string_view format, const T &... args)
std::string tolower_string(std::string_view str)
std::vector< std::string > split_on(std::string_view str, char delim)
std::optional< size_t > parse_sz(std::string_view input, bool require_canonical)
std::optional< uint32_t > parse_u32(std::string_view input, bool require_canonical)
std::vector< std::string > parse_algorithm_name(std::string_view scan_name)
std::string string_join(const std::vector< std::string > &strs, char delim)
std::optional< uint16_t > parse_u16(std::string_view input, bool require_canonical)
uint32_t to_u32bit(std::string_view input)