zen::Xml
Simple C++ XML Processing
 All Classes Namespaces Functions Variables Pages
cvrt_struc.h
1 // **************************************************************************
2 // * This file is part of the FreeFileSync project. It is distributed under *
3 // * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
4 // * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
5 // **************************************************************************
6 
7 #ifndef ZEN_XML_CONVERT_STRUC_HEADER_018727409908342709743
8 #define ZEN_XML_CONVERT_STRUC_HEADER_018727409908342709743
9 
10 #include "dom.h"
11 
12 namespace zen
13 {
20 
26 template <class T> bool readStruc(const XmlElement& input, T& value);
28 
32 template <class T> void writeStruc(const T& value, XmlElement& output);
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 //------------------------------ implementation -------------------------------------
51 namespace impl_2384343
52 {
53 ZEN_INIT_DETECT_MEMBER_TYPE(value_type);
54 ZEN_INIT_DETECT_MEMBER_TYPE(iterator);
55 ZEN_INIT_DETECT_MEMBER_TYPE(const_iterator);
56 
57 ZEN_INIT_DETECT_MEMBER(begin) //
58 ZEN_INIT_DETECT_MEMBER(end) //we don't know the exact declaration of the member attribute: may be in a base class!
59 ZEN_INIT_DETECT_MEMBER(insert) //
60 }
61 
62 template <typename T>
63 struct IsStlContainer :
64  StaticBool<
65  impl_2384343::HasMemberType_value_type <T>::value&&
66  impl_2384343::HasMemberType_iterator <T>::value&&
67  impl_2384343::HasMemberType_const_iterator<T>::value&&
68  impl_2384343::HasMember_begin <T>::value&&
69  impl_2384343::HasMember_end <T>::value&&
70  impl_2384343::HasMember_insert <T>::value> {};
71 
72 
73 namespace impl_2384343
74 {
75 ZEN_INIT_DETECT_MEMBER_TYPE(first_type);
76 ZEN_INIT_DETECT_MEMBER_TYPE(second_type);
77 
78 ZEN_INIT_DETECT_MEMBER(first) //we don't know the exact declaration of the member attribute: may be in a base class!
79 ZEN_INIT_DETECT_MEMBER(second) //
80 }
81 
82 template <typename T>
83 struct IsStlPair :
84  StaticBool<
85  impl_2384343::HasMemberType_first_type <T>::value&&
86  impl_2384343::HasMemberType_second_type<T>::value&&
87  impl_2384343::HasMember_first <T>::value&&
88  impl_2384343::HasMember_second <T>::value> {};
89 
90 //######################################################################################
91 
92 //Conversion from arbitrary types to an XML element
93 enum ValueType
94 {
95  VALUE_TYPE_STL_CONTAINER,
96  VALUE_TYPE_STL_PAIR,
97  VALUE_TYPE_OTHER,
98 };
99 
100 template <class T>
101 struct GetValueType : StaticEnum<ValueType,
102  GetTextType<T>::value != TEXT_TYPE_OTHER ? VALUE_TYPE_OTHER : //some string classes are also STL containers, so check this first
103  IsStlContainer<T>::value ? VALUE_TYPE_STL_CONTAINER :
104  IsStlPair<T>::value ? VALUE_TYPE_STL_PAIR :
105  VALUE_TYPE_OTHER> {};
106 
107 
108 template <class T, ValueType type>
109 struct ConvertElement;
110 /* -> expected interface
111 {
112  void writeStruc(const T& value, XmlElement& output) const;
113  bool readStruc(const XmlElement& input, T& value) const;
114 };
115 */
116 
117 
118 //partial specialization: handle conversion for all STL-container types!
119 template <class T>
120 struct ConvertElement<T, VALUE_TYPE_STL_CONTAINER>
121 {
122  void writeStruc(const T& value, XmlElement& output) const
123  {
124  std::for_each(value.begin(), value.end(),
125  [&](const typename T::value_type & childVal)
126  {
127  XmlElement& newChild = output.addChild("Item");
128  zen::writeStruc(childVal, newChild);
129  });
130  }
131  bool readStruc(const XmlElement& input, T& value) const
132  {
133  bool success = true;
134  value.clear();
135 
136  auto iterPair = input.getChildren("Item");
137  for (auto iter = iterPair.first; iter != iterPair.second; ++iter)
138  {
139  typename T::value_type childVal; //MSVC 2010 bug: cannot put this into a lambda body
140  if (zen::readStruc(*iter, childVal))
141  value.insert(value.end(), childVal);
142  else
143  success = false;
144  }
145  return success;
146  }
147 };
148 
149 
150 //partial specialization: handle conversion for std::pair
151 template <class T>
152 struct ConvertElement<T, VALUE_TYPE_STL_PAIR>
153 {
154  void writeStruc(const T& value, XmlElement& output) const
155  {
156  XmlElement& child1 = output.addChild("one"); //don't use "1st/2nd", this will confuse a few pedantic XML parsers
157  zen::writeStruc(value.first, child1);
158 
159  XmlElement& child2 = output.addChild("two");
160  zen::writeStruc(value.second, child2);
161  }
162  bool readStruc(const XmlElement& input, T& value) const
163  {
164  bool success = true;
165  const XmlElement* child1 = input.getChild("one");
166  if (!child1 || !zen::readStruc(*child1, value.first))
167  success = false;
168 
169  const XmlElement* child2 = input.getChild("two");
170  if (!child2 || !zen::readStruc(*child2, value.second))
171  success = false;
172 
173  return success;
174  }
175 };
176 
177 
178 //partial specialization: not a pure structured type, try text conversion (thereby respect user specializations of writeText()/readText())
179 template <class T>
180 struct ConvertElement<T, VALUE_TYPE_OTHER>
181 {
182  void writeStruc(const T& value, XmlElement& output) const
183  {
184  std::string tmp;
185  writeText(value, tmp);
186  output.setValue(tmp);
187  }
188  bool readStruc(const XmlElement& input, T& value) const
189  {
190  std::string rawStr;
191  input.getValue(rawStr);
192  return readText(rawStr, value);
193  }
194 };
195 
196 
197 template <class T> inline
198 void writeStruc(const T& value, XmlElement& output)
199 {
200  ConvertElement<T, GetValueType<T>::value>().writeStruc(value, output);
201 }
202 
203 
204 template <class T> inline
205 bool readStruc(const XmlElement& input, T& value)
206 {
207  return ConvertElement<T, GetValueType<T>::value>().readStruc(input, value);
208 }
209 }
210 
211 #endif //ZEN_XML_CONVERT_STRUC_HEADER_018727409908342709743
bool readText(const std::string &input, T &value)
Convert text to user data - used by XML elements and attributes.
Definition: cvrt_text.h:216
An XML element.
Definition: dom.h:21
bool readStruc(const XmlElement &input, T &value)
Convert XML element to structured user data.
Definition: cvrt_struc.h:205
void writeStruc(const T &value, XmlElement &output)
Convert structured user data into an XML element.
Definition: cvrt_struc.h:198
void writeText(const T &value, std::string &output)
Convert user data into text - used by XML elements and attributes.
Definition: cvrt_text.h:209