Skip to content

Commit 7abfbb1

Browse files
committed
meta ini support
1 parent b028379 commit 7abfbb1

File tree

4 files changed

+101
-13
lines changed

4 files changed

+101
-13
lines changed

kit/kit.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,21 @@ namespace kit
872872

873873
throw std::runtime_error("unable to compare values");
874874
}
875+
876+
template<class T>
877+
std::string any_to_string_type(const boost::any& a) {
878+
try{
879+
return std::to_string(boost::any_cast<T>(a));
880+
}catch(...){}
881+
return "";
882+
}
883+
884+
inline std::string any_to_string(const boost::any& a) {
885+
std::string r;
886+
{r = any_to_string_type<int>(a); if(not r.empty()) return r;}
887+
888+
throw std::runtime_error("unable to cast value");
889+
}
875890

876891
inline void ensure_starts_with(std::string& s, std::string t){
877892
if(not boost::starts_with(s,t))

kit/meta/meta.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ struct MetaElement
236236
enum class MetaFormat : unsigned {
237237
UNKNOWN=0,
238238
JSON,
239+
INI,
239240
HUMAN,
240241
//BSON
241242
};

kit/meta/meta.inl

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <boost/filesystem.hpp>
2+
#include <boost/lexical_cast.hpp>
23
#include <sstream>
34
#include "meta.h"
45
#include "../log/log.h"
@@ -373,10 +374,27 @@ std::string MetaBase<Mutex> :: serialize(MetaFormat fmt, unsigned flags) const
373374
else
374375
return root.toStyledString();
375376
}
376-
//else if (fmt == MetaFormat::BSON)
377-
//{
378-
379-
//}
377+
else if (fmt == MetaFormat::INI)
378+
{
379+
for(auto&& e: m_Elements)
380+
{
381+
std::shared_ptr<Meta> m;
382+
try{
383+
m = boost::any_cast<std::shared_ptr<Meta>>(e.value);
384+
}catch(boost::bad_any_cast&){}
385+
if(m)
386+
{
387+
data += "["+e.key+"]\n";
388+
for(auto&& j: *m)
389+
data += j.key + "=" + kit::any_to_string(j.value) + "\n";
390+
data += "\n";
391+
}
392+
else
393+
{
394+
data += e.key + "=" + kit::any_to_string(e.value) + "\n";
395+
}
396+
}
397+
}
380398
//else if (fmt == MetaFormat::HUMAN)
381399
// assert(false);
382400
else
@@ -414,7 +432,7 @@ void MetaBase<Mutex> :: deserialize(
414432

415433
template<class Mutex>
416434
void MetaBase<Mutex> :: deserialize(MetaFormat fmt, const std::string& data, const std::string& fn, const std::string& pth, unsigned flags)
417-
{
435+
{
418436
std::istringstream iss(data);
419437
deserialize(fmt, iss, fn, pth, flags);
420438
}
@@ -493,10 +511,51 @@ void MetaBase<Mutex> :: deserialize(MetaFormat fmt, std::istream& data, const st
493511
// human deserialization unsupported
494512
assert(false);
495513
}
496-
//else if (fmt == MetaFormat::BSON)
497-
//{
498-
499-
//}
514+
else if (fmt == MetaFormat::INI)
515+
{
516+
try{
517+
MetaBase<Mutex>* m = this;
518+
std::string line;
519+
while(std::getline(data, line))
520+
{
521+
if(boost::starts_with(line, "["))
522+
{
523+
auto m2 = std::make_shared<MetaBase<Mutex>>();
524+
set(line.substr(1, line.length()-2), m2);
525+
m = m2.get();
526+
}
527+
else if(not boost::starts_with(line,";") && line.length() > 1)
528+
{
529+
std::vector<std::string> toks;
530+
boost::split(toks, line, boost::is_any_of("="));
531+
auto k = toks.at(0);
532+
auto v = toks.at(1);
533+
if(v.find(".") != std::string::npos){
534+
try{
535+
auto r = boost::lexical_cast<double>(v);
536+
m->set<double>(k,r);
537+
continue;
538+
}catch(...){}
539+
}
540+
try{
541+
auto r = boost::lexical_cast<int>(v);
542+
m->set<int>(k,r);
543+
continue;
544+
}catch(...){ }
545+
if(v=="false" || v=="true")
546+
m->set<bool>(k,v=="true");
547+
else
548+
m->set<std::string>(k,v);
549+
}
550+
}
551+
}catch(...){
552+
if(fn.empty()) {
553+
K_ERROR(PARSE, "MetaBase input stream data")
554+
} else {
555+
K_ERROR(PARSE, fn);
556+
}
557+
}
558+
}
500559
else
501560
{
502561
WARNING("Unknown serialization format");
@@ -521,7 +580,8 @@ void MetaBase<Mutex> :: deserialize(const std::string& fn, unsigned flags)
521580
std::fstream file(fn, std::fstream::out); // create
522581
if(not file.good())
523582
K_ERROR(READ, fn);
524-
file << "{}\n";
583+
if(boost::ends_with(boost::to_lower_copy(fn), ".json"))
584+
file << "{}\n";
525585
file.flush();
526586
}
527587
}
@@ -829,8 +889,10 @@ template<class Mutex>
829889
/*static*/ MetaFormat MetaBase<Mutex> :: filename_to_format(const std::string& fn)
830890
{
831891
boost::filesystem::path p(fn);
832-
return p.extension().string() == ".json" ?
833-
MetaFormat::JSON:
834-
MetaFormat::UNKNOWN;
892+
if(p.extension().string() == ".json")
893+
return MetaFormat::JSON;
894+
else if(p.extension().string() == ".ini")
895+
return MetaFormat::INI;
896+
return MetaFormat::UNKNOWN;
835897
}
836898

tests/meta.test.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,16 @@ TEST_CASE("Meta","[meta]") {
227227
m->deserialize(MetaFormat::JSON,data);
228228
REQUIRE(not m->empty());
229229
REQUIRE(m->at<int>("one") == 1);
230+
231+
m->set("test", make_shared<Meta>());
232+
m->meta("test")->set("two", 2);
233+
data = m->serialize(MetaFormat::INI);
234+
m->clear();
235+
REQUIRE(m->empty());
236+
m->deserialize(MetaFormat::INI, data);
237+
REQUIRE(not m->empty());
238+
REQUIRE(m->at<int>("one") == 1);
239+
REQUIRE(m->meta("test")->at<int>("two") == 2);
230240
}
231241

232242
SECTION("arrays") {

0 commit comments

Comments
 (0)