YSTest: Configuration.cpp 源文件

YSTest PreAlpha_b400_20130424 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
Configuration.cpp
浏览该文件的文档.
1 ﻿/*
2 Copyright by FrankHB 2012 - 2013.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #include "NPL/Configuration.h"
29 #include "NPL/SContext.h"
30
31 using namespace YSLib;
32
33 YSL_BEGIN_NAMESPACE(NPL)
34
35 ValueNode
36 TransformConfiguration(const ValueNode& node)
37 {
38 auto s(node.GetSize());
39
40 if(s == 0)
41 return {0, "",
42 node ? Deliteralize(Access<string>(node)) : string()};
43
44 auto i(node.GetBegin());
45
46 if(s == 1)
47 return TransformConfiguration(*i);
48
49 const auto& new_name([&]{
50 try
51 {
52 const auto& str(Access<string>(*i));
53
54 yunseq(++i, --s);
55 return str;
56 }
57 catch(ystdex::bad_any_cast&)
58 {}
59 return string();
60 }());
61
62 if(s == 1)
63 {
64 auto&& n(TransformConfiguration(*i));
65
66 if(n.GetName().empty())
67 return {0, new_name, std::move(n.Value)};
68 return {0, new_name, ValueNode::Container{std::move(n)}};
69 }
70
71 auto p_node_cont(make_unique<ValueNode::Container>());
72
73 std::for_each(i, node.GetEnd(), [&](const ValueNode& n){
74 p_node_cont->insert(TransformConfiguration(n));
75 });
76 return {0, new_name, p_node_cont.release(), PointerTag()};
77 }
78
79
80 namespace
81 {
82
84 inline File&
85 WritePrefix(File& f, size_t n = 1, char c = '\t')
86 {
87 while(n--)
88 f << c;
89 return f;
90 }
91
92 #if 0
93
94 File&
95 WriteNode(File& f, const ValueNode& node, size_t depth)
96 {
97 if(node.GetSize() != 0)
98 for(const auto& n : node)
99 {
100 WritePrefix(f, depth);
101 f << '(' << '\n';
102 try
103 {
104 WriteNode(f, n, depth + 1);
105 }
106 catch(std::out_of_range&)
107 {}
108 WritePrefix(f, depth);
109 f << ')' << '\n';
110 }
111 return f;
112 }
113 #endif
114
116 string
117 EscapeNodeString(const string& str)
118 {
119 const char c(CheckLiteral(str));
120 auto content(MakeEscape(c == char() ? str : ystdex::get_mid(str)));
121
122 return c == char() ? std::move(content) : c + content + c;
123 }
124
126 File&
127 WriteNodeC(File& f, const ValueNode& node, size_t depth)
128 {
129 WritePrefix(f, depth);
130 f << node.GetName();
131 if(node)
132 {
133 try
134 {
135 const auto& s(Access<string>(node));
136
137 f << ' ' << '"' << EscapeNodeString(s) << '"' << '\n';
138 return f;
139 }
140 catch(ystdex::bad_any_cast&)
141 {}
142 f << '\n';
143 for(const auto& n : node)
144 {
145 WritePrefix(f, depth);
146 f << '(' << '\n';
147 try
148 {
149 WriteNodeC(f, n, depth + 1);
150 }
151 catch(std::out_of_range&)
152 {}
153 WritePrefix(f, depth);
154 f << ')' << '\n';
155 }
156 }
157 return f;
158 }
159
160 } // unnamed namespace;
161
162 File&
163 operator<<(File& f, const Configuration& conf)
164 {
165 return WriteNodeC(f, conf.GetRoot(), 0);
166 }
167
168 TextFile&
169 operator>>(TextFile& tf, Configuration& conf)
170 {
171 try
172 {
173 tf.Rewind();
174 conf.root = TransformConfiguration(SContext::Analyze(Session(tf)));
175 }
176 catch(ystdex::bad_any_cast& e)
177 {
178 // TODO: Avoid memory allocation.
179 throw LoggedEvent(ystdex::sfmt(
180 "Bad configuration found: cast failed from [%s] to [%s] .",
181 e.from(), e.to()), 0x80);
182 }
183 return tf;
184 }
185
186 YSL_END_NAMESPACE(NPL)
187