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 
34 
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&
170 {
171  try
172  {
173  tf.Rewind();
175  }
176  catch(ystdex::bad_any_cast& e)
177  {
178  // TODO: Avoid memory allocation.
180  "Bad configuration found: cast failed from [%s] to [%s] .",
181  e.from(), e.to()), 0x80);
182  }
183  return tf;
184 }
185 
187