X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fcommon%2Fstr_map.cc;fp=src%2Fceph%2Fsrc%2Fcommon%2Fstr_map.cc;h=c3f6a2b6519e3c5b2597fd0ed7082de8c044d67e;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/common/str_map.cc b/src/ceph/src/common/str_map.cc new file mode 100644 index 0000000..c3f6a2b --- /dev/null +++ b/src/ceph/src/common/str_map.cc @@ -0,0 +1,163 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013 Cloudwatt + * + * Author: Loic Dachary + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + */ + +#include "include/str_map.h" +#include "include/str_list.h" + +#include "json_spirit/json_spirit.h" + +using namespace std; + +int get_json_str_map( + const string &str, + ostream &ss, + map *str_map, + bool fallback_to_plain) +{ + json_spirit::mValue json; + try { + // try json parsing first + + json_spirit::read_or_throw(str, json); + + if (json.type() != json_spirit::obj_type) { + ss << str << " must be a JSON object but is of type " + << json.type() << " instead"; + return -EINVAL; + } + + json_spirit::mObject o = json.get_obj(); + + for (map::iterator i = o.begin(); + i != o.end(); + ++i) { + (*str_map)[i->first] = i->second.get_str(); + } + } catch (json_spirit::Error_position &e) { + if (fallback_to_plain) { + // fallback to key=value format + get_str_map(str, str_map, "\t\n "); + } else { + return -EINVAL; + } + } + return 0; +} +string trim(const string& str) { + size_t start = 0; + size_t end = str.size() - 1; + while (isspace(str[start]) != 0 && start <= end) { + ++start; + } + while (isspace(str[end]) != 0 && start <= end) { + --end; + } + if (start <= end) { + return str.substr(start, end - start + 1); + } + return string(); +} + +int get_str_map( + const string &str, + map *str_map, + const char *delims) +{ + list pairs; + get_str_list(str, delims, pairs); + for (list::iterator i = pairs.begin(); i != pairs.end(); ++i) { + size_t equal = i->find('='); + if (equal == string::npos) + (*str_map)[*i] = string(); + else { + const string key = trim(i->substr(0, equal)); + equal++; + const string value = trim(i->substr(equal)); + (*str_map)[key] = value; + } + } + return 0; +} + +string get_str_map_value( + const map &str_map, + const string &key, + const string *def_val) +{ + map::const_iterator p = str_map.find(key); + + // key exists in str_map + if (p != str_map.end()) { + // but value is empty + if (p->second.empty()) + return p->first; + // and value is not empty + return p->second; + } + + // key DNE in str_map and def_val was specified + if (def_val != NULL) + return *def_val; + + // key DNE in str_map, no def_val was specified + return string(); +} + +string get_str_map_key( + const map &str_map, + const string &key, + const string *fallback_key) +{ + map::const_iterator p = str_map.find(key); + if (p != str_map.end()) + return p->second; + + if (fallback_key != NULL) { + p = str_map.find(*fallback_key); + if (p != str_map.end()) + return p->second; + } + return string(); +} + +// This function's only purpose is to check whether a given map has only +// ONE key with an empty value (which would mean that 'get_str_map()' read +// a map in the form of 'VALUE', without any KEY/VALUE pairs) and, in such +// event, to assign said 'VALUE' to a given 'def_key', such that we end up +// with a map of the form "m = { 'def_key' : 'VALUE' }" instead of the +// original "m = { 'VALUE' : '' }". +int get_conf_str_map_helper( + const string &str, + ostringstream &oss, + map *m, + const string &def_key) +{ + int r = get_str_map(str, m); + + if (r < 0) { + return r; + } + + if (r >= 0 && m->size() == 1) { + map::iterator p = m->begin(); + if (p->second.empty()) { + string s = p->first; + m->erase(s); + (*m)[def_key] = s; + } + } + return r; +}