mirror of
https://github.com/ceph/ceph
synced 2025-04-11 04:02:04 +00:00
common: implement get_str_map to parse key/values
It is capable of parsing json or key=value pairs. The prototype is made to look like get_str_list. The implementation is in common + include and use .h. It will probably be moved to common and use .hpp instead, along with str_list.{cc,h}. Signed-off-by: Loic Dachary <loic@dachary.org>
This commit is contained in:
parent
df1704eeb0
commit
a44a57a7c3
@ -29,6 +29,7 @@ libcommon_la_SOURCES = \
|
||||
common/safe_io.c \
|
||||
common/snap_types.cc \
|
||||
common/str_list.cc \
|
||||
common/str_map.cc \
|
||||
common/errno.cc \
|
||||
common/RefCountedObj.cc \
|
||||
common/blkdev.cc \
|
||||
|
68
src/common/str_map.cc
Normal file
68
src/common/str_map.cc
Normal file
@ -0,0 +1,68 @@
|
||||
// -*- 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 <libre.licensing@cloudwatt.com>
|
||||
*
|
||||
* Author: Loic Dachary <loic@dachary.org>
|
||||
*
|
||||
* 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 <errno.h>
|
||||
|
||||
#include "include/str_map.h"
|
||||
#include "include/str_list.h"
|
||||
|
||||
#include "json_spirit/json_spirit.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int get_str_map(const string &str,
|
||||
stringstream &ss,
|
||||
map<string,string> *str_map)
|
||||
{
|
||||
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<string, json_spirit::mValue>::iterator i = o.begin();
|
||||
i != o.end();
|
||||
++i) {
|
||||
(*str_map)[i->first] = i->second.get_str();
|
||||
}
|
||||
|
||||
} catch (json_spirit::Error_position &e) {
|
||||
// fallback to key=value format
|
||||
|
||||
list<string> pairs;
|
||||
get_str_list(str, "\t\n ", pairs);
|
||||
for (list<string>::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 = i->substr(0, equal);
|
||||
equal++;
|
||||
const string value = i->substr(equal);
|
||||
(*str_map)[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -59,6 +59,7 @@ noinst_HEADERS += \
|
||||
include/rbd_types.h \
|
||||
include/statlite.h \
|
||||
include/str_list.h \
|
||||
include/str_map.h \
|
||||
include/stringify.h \
|
||||
include/triple.h \
|
||||
include/types.h \
|
||||
|
59
src/include/str_map.h
Normal file
59
src/include/str_map.h
Normal file
@ -0,0 +1,59 @@
|
||||
// -*- 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 <libre.licensing@cloudwatt.com>
|
||||
*
|
||||
* Author: Loic Dachary <loic@dachary.org>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CEPH_STRMAP_H
|
||||
#define CEPH_STRMAP_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
/**
|
||||
* Parse **str** and set **str_map** with the key/value pairs read
|
||||
* from it. The format of **str** is either a well formed JSON object
|
||||
* or a custom key[=value] plain text format.
|
||||
*
|
||||
* JSON is tried first. If successfully parsed into a JSON object, it
|
||||
* is copied into **str_map** verbatim. If it is not a JSON object ( a
|
||||
* string, integer etc. ), -EINVAL is returned and **ss** is set to
|
||||
* a human readable error message.
|
||||
*
|
||||
* If **str** is no valid JSON, it is assumed to be a string
|
||||
* containing white space separated key=value pairs. A white space is
|
||||
* either space, tab or newline. The value is optional, in which case
|
||||
* it defaults to an empty string. For example:
|
||||
*
|
||||
* insert your own=political statement=here
|
||||
*
|
||||
* will be parsed into:
|
||||
*
|
||||
* { "insert": "",
|
||||
* "your": "",
|
||||
* "own": "policital",
|
||||
* "statement": "here" }
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*
|
||||
* @param [in] str JSON or plain text key/value pairs
|
||||
* @param [out] ss human readable message on error
|
||||
* @param [out] str_map key/value pairs read from str
|
||||
* @return **0** on success or a -EINVAL on error.
|
||||
*/
|
||||
extern int get_str_map(const std::string &str,
|
||||
std::stringstream &ss,
|
||||
std::map<std::string,std::string> *str_map);
|
||||
|
||||
#endif
|
@ -268,6 +268,11 @@ unittest_bloom_filter_CXXFLAGS = $(UNITTEST_CXXFLAGS)
|
||||
unittest_bloom_filter_LDADD = $(UNITTEST_LDADD) $(CEPH_GLOBAL)
|
||||
check_PROGRAMS += unittest_bloom_filter
|
||||
|
||||
unittest_str_map_SOURCES = test/common/test_str_map.cc
|
||||
unittest_str_map_CXXFLAGS = $(UNITTEST_CXXFLAGS)
|
||||
unittest_str_map_LDADD = $(UNITTEST_LDADD) $(CEPH_GLOBAL)
|
||||
check_PROGRAMS += unittest_str_map
|
||||
|
||||
unittest_sharedptr_registry_SOURCES = test/common/test_sharedptr_registry.cc
|
||||
unittest_sharedptr_registry_CXXFLAGS = $(UNITTEST_CXXFLAGS)
|
||||
unittest_sharedptr_registry_LDADD = $(UNITTEST_LDADD) $(CEPH_GLOBAL)
|
||||
|
70
src/test/common/test_str_map.cc
Normal file
70
src/test/common/test_str_map.cc
Normal file
@ -0,0 +1,70 @@
|
||||
// -*- 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 <libre.licensing@cloudwatt.com>
|
||||
*
|
||||
* Author: Loic Dachary <loic@dachary.org>
|
||||
*
|
||||
* 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 <errno.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "include/str_map.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
TEST(str_map, json) {
|
||||
map<string,string> str_map;
|
||||
stringstream ss;
|
||||
// well formatted
|
||||
ASSERT_EQ(0, get_str_map("{\"key\": \"value\"}", ss, &str_map));
|
||||
ASSERT_EQ("value", str_map["key"]);
|
||||
// well formatted but not a JSON object
|
||||
ASSERT_EQ(-EINVAL, get_str_map("\"key\"", ss, &str_map));
|
||||
ASSERT_NE(string::npos, ss.str().find("must be a JSON object"));
|
||||
}
|
||||
|
||||
TEST(str_map, plaintext) {
|
||||
stringstream ss;
|
||||
{
|
||||
map<string,string> str_map;
|
||||
ASSERT_EQ(0, get_str_map(" foo=bar\t\nfrob=nitz yeah right= \n\t",
|
||||
ss, &str_map));
|
||||
ASSERT_EQ(4u, str_map.size());
|
||||
ASSERT_EQ("bar", str_map["foo"]);
|
||||
ASSERT_EQ("nitz", str_map["frob"]);
|
||||
ASSERT_EQ("", str_map["yeah"]);
|
||||
ASSERT_EQ("", str_map["right"]);
|
||||
}
|
||||
{
|
||||
map<string,string> str_map;
|
||||
ASSERT_EQ(0, get_str_map("that", ss, &str_map));
|
||||
ASSERT_EQ(1u, str_map.size());
|
||||
ASSERT_EQ("", str_map["that"]);
|
||||
}
|
||||
{
|
||||
map<string,string> str_map;
|
||||
ASSERT_EQ(0, get_str_map(" \t \n ", ss, &str_map));
|
||||
ASSERT_EQ(0u, str_map.size());
|
||||
ASSERT_EQ(0, get_str_map("", ss, &str_map));
|
||||
ASSERT_EQ(0u, str_map.size());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* compile-command: "cd ../.. ; make -j4 &&
|
||||
* make unittest_str_map &&
|
||||
* valgrind --tool=memcheck --leak-check=full \
|
||||
* ./unittest_str_map
|
||||
* "
|
||||
* End:
|
||||
*/
|
Loading…
Reference in New Issue
Block a user