zen::Xml: cvrt_struc.h Source File

| zen::Xml Simple C++ XML Processing

- Main Page
- Namespaces
- Classes

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
zen::readText
bool readText(const std::string &input, T &value)
Convert text to user data - used by XML elements and attributes.
Definition: cvrt_text.h:214
zen::XmlElement
An XML element.
Definition: dom.h:20
zen
The zen::Xml namespace.
Definition: bind.h:15
zen::readStruc
bool readStruc(const XmlElement &input, T &value)
Convert XML element to structured user data.
Definition: cvrt_struc.h:204
zen::writeStruc
void writeStruc(const T &value, XmlElement &output)
Convert structured user data into an XML element.
Definition: cvrt_struc.h:197
zen::writeText
void writeText(const T &value, std::string &output)
Convert user data into text - used by XML elements and attributes.
Definition: cvrt_text.h:207