/// Deconstruct a "URI" string into the "fllename" part (returned) and turn /// the "query" part into a series of pairs of id and value. For example, /// deconstruct_uri("foo.tif?bar=1&blah=\"hello world\"", args) /// would be expected to return "foo.tif" and *args would contain two /// pairs: ("foo","1") and ("bar","\"hello world\""). static string_view deconstruct_uri (string_view uri, std::vector<std::pair<string_view,string_view> > *args=NULL) { if (args) args->clear (); size_t arg_start = uri.find ('?'); if (arg_start == string_view::npos) return uri; string_view argstring = uri.substr (arg_start+1); string_view filename = uri.substr (0, arg_start); if (! args) return filename; while (! argstring.empty()) { string_view id = Strutil::parse_until (argstring, "=&"); string_view value; if (! id.size()) break; if (! Strutil::parse_char (argstring, '=') || argstring.empty()) break; if (argstring[0] == '\"') Strutil::parse_string (argstring, value, true, Strutil::KeepQuotes); else value = Strutil::parse_until (argstring, "&\t\r\n"); args->push_back (std::make_pair(id, value)); Strutil::parse_char (argstring, '&'); } return filename; }
config_option::config_option(string_view category, string_view name, string_view description, const meta_state* meta, void* value) : meta_(meta), value_(value) { using std::copy; using std::accumulate; auto comma = name.find(','); auto long_name = name.substr(0, comma); auto short_names = comma == string_view::npos ? string_view{} : name.substr(comma + 1); auto total_size = [](std::initializer_list<string_view> xs) { return (xs.size() - 1) // one separator between all fields + accumulate(xs.begin(), xs.end(), size_t{0}, [](size_t x, string_view sv) { return x + sv.size(); }); }; auto ts = total_size({category, long_name, short_names, description}); CAF_ASSERT(ts <= std::numeric_limits<uint16_t>::max()); buf_size_ = static_cast<uint16_t>(ts); buf_.reset(new char[ts]); // fille the buffer with "<category>.<long-name>,<short-name>,<descriptions>" auto first = buf_.get(); auto i = first; auto pos = [&] { return static_cast<uint16_t>(std::distance(first, i)); }; // <category>. i = copy(category.begin(), category.end(), i); category_separator_ = pos(); *i++ = '.'; // <long-name>, i = copy(long_name.begin(), long_name.end(), i); long_name_separator_ = pos(); *i++ = ','; // <short-names>, i = copy(short_names.begin(), short_names.end(), i); short_names_separator_ = pos(); *i++ = ','; // <description> i = copy(description.begin(), description.end(), i); CAF_ASSERT(pos() == buf_size_); }
static lng_line_type parse_lng_line(const string_view str, bool ParseLabels, string_view& Label, string_view& Data) { Label = {}; Data = {}; //-- "Text" if (starts_with(str, L'"')) { Data = str.substr(1, str.size() - (ends_with(str, L'"')? 2 : 1)); return lng_line_type::text; } //-- //[Label] if (ParseLabels) { const auto Prefix = L"//["sv, Suffix = L"]"sv; if (starts_with(str, Prefix) && ends_with(str, Suffix)) { Label = str.substr(Prefix.size(), str.size() - Prefix.size() - Suffix.size()); return lng_line_type::label; } } //-- MLabel="Text" if (ParseLabels && !str.empty() && str.back() == L'"') { const auto eq_pos = str.find(L'='); if (eq_pos != str.npos && std::iswalpha(str[0])) { const auto Value = trim(str.substr(eq_pos + 1)); if (starts_with(Value, L'"')) { Label = trim(str.substr(0, eq_pos)); Data = Value.substr(1, Value.size() - 2); return lng_line_type::both; } } } return lng_line_type::none; }
static void parse_lng_line(const string_view str, string& label, string& data, bool& have_data) { have_data = false; //-- //[Label] if (starts_with(str, L"//["sv) && ends_with(str, L"]"sv)) { const auto LabelView = str.substr(3, str.size() - 3 - 1); //-- //[Label=0] assign(label, LabelView.substr(0, LabelView.find(L'='))); return; } //-- "Text" if (starts_with(str, L'"')) { have_data = true; assign(data, str.substr(1)); if (!data.empty() && data.back() == L'"') data.pop_back(); return; } //-- MLabel="Text" if (!str.empty() && str.back() == L'"') { const auto eq_pos = str.find(L'='); if (eq_pos != string::npos && InRange(L'A', upper(str[0]), L'Z')) { assign(data, trim(str.substr(eq_pos + 1))); if (data.size() > 1 && data[0] == L'"') { assign(label, trim(str.substr(0, eq_pos))); have_data = true; data.pop_back(); data.erase(0, 1); } } } }
void f2(const string_view str) { cout << str.substr(str.find("D"), 3) << endl; }