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-3.0 *
4 // * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
5 // *****************************************************************************
6 
7 #ifndef CVRT_STRUC_H_018727409908342709743
8 #define CVRT_STRUC_H_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  for (const typename T::value_type& childVal : value)
125  {
126  XmlElement& newChild = output.addChild("Item");
127  zen::writeStruc(childVal, newChild);
128  }
129  }
130  bool readStruc(const XmlElement& input, T& value) const
131  {
132  bool success = true;
133  value.clear();
134 
135  auto itPair = input.getChildren("Item");
136  for (auto it = itPair.first; it != itPair.second; ++it)
137  {
138  typename T::value_type childVal; //MSVC 2010 bug: cannot put this into a lambda body
139  if (zen::readStruc(*it, childVal))
140  value.insert(value.end(), childVal);
141  else
142  success = false;
143  }
144  return success;
145  }
146 };
147 
148 
149 //partial specialization: handle conversion for std::pair
150 template <class T>
151 struct ConvertElement<T, VALUE_TYPE_STL_PAIR>
152 {
153  void writeStruc(const T& value, XmlElement& output) const
154  {
155  XmlElement& child1 = output.addChild("one"); //don't use "1st/2nd", this will confuse a few pedantic XML parsers
156  zen::writeStruc(value.first, child1);
157 
158  XmlElement& child2 = output.addChild("two");
159  zen::writeStruc(value.second, child2);
160  }
161  bool readStruc(const XmlElement& input, T& value) const
162  {
163  bool success = true;
164  const XmlElement* child1 = input.getChild("one");
165  if (!child1 || !zen::readStruc(*child1, value.first))
166  success = false;
167 
168  const XmlElement* child2 = input.getChild("two");
169  if (!child2 || !zen::readStruc(*child2, value.second))
170  success = false;
171 
172  return success;
173  }
174 };
175 
176 
177 //partial specialization: not a pure structured type, try text conversion (thereby respect user specializations of writeText()/readText())
178 template <class T>
179 struct ConvertElement<T, VALUE_TYPE_OTHER>
180 {
181  void writeStruc(const T& value, XmlElement& output) const
182  {
183  std::string tmp;
184  writeText(value, tmp);
185  output.setValue(tmp);
186  }
187  bool readStruc(const XmlElement& input, T& value) const
188  {
189  std::string rawStr;
190  input.getValue(rawStr);
191  return readText(rawStr, value);
192  }
193 };
194 
195 
196 template <class T> inline
197 void writeStruc(const T& value, XmlElement& output)
198 {
199  ConvertElement<T, GetValueType<T>::value>().writeStruc(value, output);
200 }
201 
202 
203 template <class T> inline
204 bool readStruc(const XmlElement& input, T& value)
205 {
206  return ConvertElement<T, GetValueType<T>::value>().readStruc(input, value);
207 }
208 }
209 
210 #endif //CVRT_STRUC_H_018727409908342709743
bool readText(const std::string &input, T &value)
Convert text to user data - used by XML elements and attributes.
Definition: cvrt_text.h:214
An XML element.
Definition: dom.h:20
The zen::Xml namespace.
Definition: bind.h:15
bool readStruc(const XmlElement &input, T &value)
Convert XML element to structured user data.
Definition: cvrt_struc.h:204
void writeStruc(const T &value, XmlElement &output)
Convert structured user data into an XML element.
Definition: cvrt_struc.h:197
void writeText(const T &value, std::string &output)
Convert user data into text - used by XML elements and attributes.
Definition: cvrt_text.h:207