]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/str_map.cc
638a307845cb8401b72896525b187f8d377a25f3
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
8 * Author: Loic Dachary <loic@dachary.org>
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.
17 #include "include/str_map.h"
18 #include "include/str_list.h"
20 #include <boost/algorithm/string.hpp>
22 #include "json_spirit/json_spirit.h"
30 bool fallback_to_plain
)
32 json_spirit::mValue json
;
34 // try json parsing first
36 json_spirit::read_or_throw(str
, json
);
38 if (json
.type() != json_spirit::obj_type
) {
39 ss
<< str
<< " must be a JSON object but is of type "
40 << json
.type() << " instead";
44 json_spirit::mObject o
= json
.get_obj();
46 for (map
<string
, json_spirit::mValue
>::iterator i
= o
.begin();
49 (*str_map
)[i
->first
] = i
->second
.get_str();
51 } catch (json_spirit::Error_position
&e
) {
52 if (fallback_to_plain
) {
53 // fallback to key=value format
54 get_str_map(str
, str_map
, "\t\n ");
62 static std::string_view
trim(std::string_view str
)
64 static const char* whitespaces
= "\t\n ";
65 auto beg
= str
.find_first_not_of(whitespaces
);
66 if (beg
== str
.npos
) {
69 auto end
= str
.find_last_not_of(whitespaces
);
70 return str
.substr(beg
, end
- beg
+ 1);
78 for_each_pair(str
, delims
, [str_map
](std::string_view key
,
79 std::string_view val
) {
80 // is the format 'K=V' or just 'K'?
82 str_map
->emplace(std::string(key
), "");
84 str_map
->emplace(std::string(trim(key
)), std::string(trim(val
)));
90 str_map_t
get_str_map(
95 get_str_map(str
, &str_map
, delim
);
99 string
get_str_map_value(
100 const str_map_t
&str_map
,
102 const string
*def_val
)
104 auto p
= str_map
.find(key
);
106 // key exists in str_map
107 if (p
!= str_map
.end()) {
108 // but value is empty
109 if (p
->second
.empty())
111 // and value is not empty
115 // key DNE in str_map and def_val was specified
116 if (def_val
!= nullptr)
119 // key DNE in str_map, no def_val was specified
123 string
get_str_map_key(
124 const str_map_t
&str_map
,
126 const string
*fallback_key
)
128 auto p
= str_map
.find(key
);
129 if (p
!= str_map
.end())
132 if (fallback_key
!= nullptr) {
133 p
= str_map
.find(*fallback_key
);
134 if (p
!= str_map
.end())
140 // This function's only purpose is to check whether a given map has only
141 // ONE key with an empty value (which would mean that 'get_str_map()' read
142 // a map in the form of 'VALUE', without any KEY/VALUE pairs) and, in such
143 // event, to assign said 'VALUE' to a given 'def_key', such that we end up
144 // with a map of the form "m = { 'def_key' : 'VALUE' }" instead of the
145 // original "m = { 'VALUE' : '' }".
146 int get_conf_str_map_helper(
150 const string
&default_key
)
152 get_str_map(str
, str_map
);
154 if (str_map
->size() == 1) {
155 auto p
= str_map
->begin();
156 if (p
->second
.empty()) {
159 (*str_map
)[default_key
] = s
;
165 std::string
get_value_via_strmap(
166 const string
& conf_string
,
167 std::string_view default_key
)
169 auto mp
= get_str_map(conf_string
);
170 if (mp
.size() != 1) {
174 // if the one-elem "map" is of the form { 'value' : '' }
175 // replace it with { 'default_key' : 'value' }
176 const auto& [k
, v
] = *(mp
.begin());
183 std::string
get_value_via_strmap(
184 const string
& conf_string
,
186 std::string_view default_key
)
188 auto mp
= get_str_map(conf_string
);
189 if (mp
.size() != 1) {
190 return std::string
{};
193 // if the one-elem "map" is of the form { 'value' : '' }
194 // replace it with { 'default_key' : 'value' }
195 const auto& [k
, v
] = *(mp
.begin());
202 if (k
== default_key
) {