-
Notifications
You must be signed in to change notification settings - Fork 0
/
yaml-firebreath.cpp
106 lines (96 loc) · 3.66 KB
/
yaml-firebreath.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**********************************************************\
Original Author: Richard Bateman
Created: Jun 28, 2011
License: Dual license model; choose one of two:
New BSD License
http://www.opensource.org/licenses/bsd-license.php
- or -
GNU Lesser General Public License, version 2.1
http://www.gnu.org/licenses/lgpl-2.1.html
Copyright 2011 Facebook, Inc
\**********************************************************/
#include "yaml-firebreath.h"
#include <fstream>
#include "APITypes.h"
#include "variant.h"
#include "yaml-cpp/yaml.h"
namespace FB {
void emitVariantAsYamlFile(const variant& val, const std::string& filename) {
std::ofstream myfile;
myfile.open(filename.c_str());
if (myfile.fail()) {
throw new std::runtime_error("Could not open config file");
}
YAML::Emitter emitter(myfile);
emitVariantAsYaml(emitter, val);
myfile.close();
}
void emitVariantAsYaml(YAML::Emitter& out, const variant &val)
{
if (val.is_of_type<std::string>()) {
out << val.convert_cast<std::string>();
} else if (val.is_of_type<VariantMap>()) {
out << YAML::BeginMap;
VariantMap map = val.cast<VariantMap>();
for (VariantMap::iterator it = map.begin(); it != map.end(); ++it) {
out << YAML::Key << it->first;
out << YAML::Value;
emitVariantAsYaml(out, it->second);
}
out << YAML::EndMap;
} else if (val.is_of_type<VariantList>()) {
out << YAML::BeginSeq;
VariantList list = val.cast<VariantList>();
for (VariantList::iterator it = list.begin(); it != list.end(); ++it) {
emitVariantAsYaml(out, *it);
}
out << YAML::EndSeq;
} else if (val.is_of_type<int>()
|| val.is_of_type<char>()
|| val.is_of_type<short>()
|| val.is_of_type<long>()) {
out << val.convert_cast<long>();
} else if (val.is_of_type<unsigned int>()
|| val.is_of_type<unsigned short>()
|| val.is_of_type<unsigned char>()
|| val.is_of_type<unsigned long>()) {
out << val.convert_cast<unsigned long>();
} else if (val.is_of_type<double>() || val.is_of_type<float>()) {
out << val.convert_cast<double>();
} else if (val.is_of_type<bool>()) {
out << val.convert_cast<bool>();
} else {
out << YAML::Null;
}
}
variant loadYamlFileToVariant(const std::string& filename) {
YAML::Node doc = YAML::LoadFile(filename);
return yamlNodeToVariant(doc);
}
variant yamlNodeToVariant(const YAML::Node& node) {
// recursive depth first
std::string outStr;
if (node.IsScalar()) {
return node.as<std::string>();
} else if (node.IsSequence()) {
VariantList list;
for (unsigned int i = 0; i < node.size(); i++) {
const YAML::Node & subnode = node[i];
list.push_back(yamlNodeToVariant(subnode));
}
return list;
} else if (node.IsMap()) {
VariantMap map;
for (YAML::const_iterator i = node.begin(); i != node.end(); ++i) {
const YAML::Node & key = i->first;
const YAML::Node & value = i->second;
map[key.as<std::string>()] = yamlNodeToVariant(value);
}
return map;
} else if (node.IsNull()) {
return FBNull();
} else {
return FBVoid();
}
}
};