]> git.proxmox.com Git - ceph.git/blame - ceph/src/include/str_map.h
update ceph source to reef 18.2.1
[ceph.git] / ceph / src / include / str_map.h
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
7 *
8 * Author: Loic Dachary <loic@dachary.org>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 */
16
17#ifndef CEPH_STRMAP_H
18#define CEPH_STRMAP_H
19
20#define CONST_DELIMS ",;\t\n "
21
22#include <map>
23#include <string>
24#include <sstream>
25
20effc67
TL
26template <typename Func>
27void for_each_pair(std::string_view s, const char* delims, Func&& f)
28{
29 auto pos = s.find_first_not_of(delims);
30 while (pos != s.npos) {
31 s.remove_prefix(pos); // trim delims from the front
32 auto end = s.find_first_of(delims);
33 auto kv = s.substr(0, end);
34 if (auto equal = kv.find('='); equal != kv.npos) {
35 f(kv.substr(0, equal), kv.substr(equal + 1));
36 } else {
37 f(kv.substr(0, equal), std::string_view());
38 }
39 pos = s.find_first_not_of(delims, end);
40 }
41}
42
43using str_map_t = std::map<std::string,std::string>;
44
7c673cae
FG
45/**
46 * Parse **str** and set **str_map** with the key/value pairs read
47 * from it. The format of **str** is either a well formed JSON object
48 * or a custom key[=value] plain text format.
49 *
50 * JSON is tried first. If successfully parsed into a JSON object, it
51 * is copied into **str_map** verbatim. If it is not a JSON object ( a
52 * string, integer etc. ), -EINVAL is returned and **ss** is set to
53 * a human readable error message.
54 *
55 * If **str** is no valid JSON and if **fallback_to_plain** is set to true
56 * (default: true) it is assumed to be a string containing white space
57 * separated key=value pairs. A white space is either space, tab or newline.
58 * Function **get_str_map** will be leveraged to parse the plain-text
59 * key/value pairs.
60 *
61 * @param [in] str JSON or plain text key/value pairs
62 * @param [out] ss human readable message on error
63 * @param [out] str_map key/value pairs read from str
64 * @param [in] fallback_to_plain attempt parsing as plain-text if json fails
65 * @return **0** on success or a -EINVAL on error.
66 */
20effc67 67int get_json_str_map(
7c673cae
FG
68 const std::string &str,
69 std::ostream &ss,
20effc67 70 str_map_t* str_map,
7c673cae
FG
71 bool fallback_to_plain = true);
72
73/**
74 * Parse **str** and set **str_map** with the key/value pairs read from
75 * it. The format of **str** is a number of custom key[=value] pairs in
76 * plain text format.
77 *
78 * The string will be parsed taking **delims** as field delimiters for
79 * key/values. The value is optional resulting in an empty string when
80 * not provided. For example, using white space as delimiters:
81 *
82 * insert your own=political/ideological statement=here
83 *
84 * will be parsed into:
85 *
86 * { "insert": "",
87 * "your": "",
88 * "own": "political/ideological",
89 * "statement": "here" }
90 *
91 * Alternative delimiters may be provided. For instance, specifying
92 * "white space and slash", for the above statement, would be parsed
93 * into:
94 *
95 * { "insert": "",
96 * "your": "",
97 * "own": "political",
98 * "ideological": "",
99 * "statement": "here" }
100 *
101 * See how adding '/' to the delimiters field will spawn a new key without
102 * a set value.
103 *
104 * Always returns 0, as there is no condition for failure.
105 *
106 * @param [in] str plain text key/value pairs
107 * @param [in] delims field delimiters to be used for parsing str
108 * @param [out] str_map key/value pairs parsed from str
109 * @return **0**
110 */
20effc67 111int get_str_map(
7c673cae 112 const std::string &str,
20effc67 113 str_map_t* str_map,
7c673cae
FG
114 const char *delims = CONST_DELIMS);
115
20effc67
TL
116// an alternate form (as we never fail):
117str_map_t get_str_map(
118 const std::string& str,
119 const char* delim = CONST_DELIMS);
120
7c673cae
FG
121/**
122 * Returns the value of **key** in **str_map** if available.
123 *
124 * If **key** is not available in **str_map**, and if **def_val** is
125 * not-NULL then returns **def_val**. Otherwise checks if the value of
126 * **key** is an empty string and if so will return **key**.
127 * If the map contains **key**, the function returns the value of **key**.
128 *
129 * @param[in] str_map Map to obtain **key** from
130 * @param[in] key The key to search for in the map
131 * @param[in] def_val The value to return in case **key** is not present
132 */
20effc67
TL
133std::string get_str_map_value(
134 const str_map_t& str_map,
7c673cae 135 const std::string &key,
20effc67 136 const std::string *def_val = nullptr);
7c673cae
FG
137
138/**
139 * Returns the value of **key** in **str_map** if available.
140 *
141 * If **key** is available in **str_map** returns the value of **key**.
142 *
143 * If **key** is not available in **str_map**, and if **def_key**
144 * is not-NULL and available in **str_map**, then returns the value
145 * of **def_key**.
146 *
147 * Otherwise returns an empty string.
148 *
149 * @param[in] str_map Map to obtain **key** or **def_key** from
150 * @param[in] key Key to obtain the value of from **str_map**
151 * @param[in] def_key Key to fallback to if **key** is not present
152 * in **str_map**
153 */
20effc67
TL
154std::string get_str_map_key(
155 const str_map_t& str_map,
7c673cae 156 const std::string &key,
20effc67 157 const std::string *fallback_key = nullptr);
7c673cae
FG
158
159// This function's only purpose is to check whether a given map has only
160// ONE key with an empty value (which would mean that 'get_str_map()' read
161// a map in the form of 'VALUE', without any KEY/VALUE pairs) and, in such
162// event, to assign said 'VALUE' to a given 'def_key', such that we end up
163// with a map of the form "m = { 'def_key' : 'VALUE' }" instead of the
164// original "m = { 'VALUE' : '' }".
165int get_conf_str_map_helper(
166 const std::string &str,
167 std::ostringstream &oss,
20effc67
TL
168 str_map_t* str_map,
169 const std::string &default_key);
170
171std::string get_value_via_strmap(
172 const std::string& conf_string,
173 std::string_view default_key);
174
175std::string get_value_via_strmap(
176 const std::string& conf_string,
177 const std::string& key,
178 std::string_view default_key);
7c673cae
FG
179
180#endif