summaryrefslogtreecommitdiff
path: root/zenXml/zenxml/cvrt_struc.h
diff options
context:
space:
mode:
authorDaniel Wilhelm <shieldwed@outlook.com>2017-03-12 22:00:35 -0600
committerDaniel Wilhelm <shieldwed@outlook.com>2017-03-12 22:00:35 -0600
commit3ba62ef1de77153e5a8c7bad4451b96f6a1678b0 (patch)
treee6e69717e394a528a2e2aca3af036d4befaa9658 /zenXml/zenxml/cvrt_struc.h
parent8.9 (diff)
downloadFreeFileSync-3ba62ef1de77153e5a8c7bad4451b96f6a1678b0.tar.gz
FreeFileSync-3ba62ef1de77153e5a8c7bad4451b96f6a1678b0.tar.bz2
FreeFileSync-3ba62ef1de77153e5a8c7bad4451b96f6a1678b0.zip
8.10
Diffstat (limited to 'zenXml/zenxml/cvrt_struc.h')
-rwxr-xr-xzenXml/zenxml/cvrt_struc.h210
1 files changed, 210 insertions, 0 deletions
diff --git a/zenXml/zenxml/cvrt_struc.h b/zenXml/zenxml/cvrt_struc.h
new file mode 100755
index 00000000..7797c0fe
--- /dev/null
+++ b/zenXml/zenxml/cvrt_struc.h
@@ -0,0 +1,210 @@
+// *****************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
+// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
+// *****************************************************************************
+
+#ifndef CVRT_STRUC_H_018727409908342709743
+#define CVRT_STRUC_H_018727409908342709743
+
+#include "dom.h"
+
+namespace zen
+{
+/**
+\file
+\brief Handle conversion of arbitrary types to and from XML elements.
+See comments in cvrt_text.h
+*/
+
+///Convert XML element to structured user data
+/**
+ \param input The input XML element.
+ \param value Conversion target value.
+ \return "true" if value was read successfully.
+*/
+template <class T> bool readStruc(const XmlElement& input, T& value);
+///Convert structured user data into an XML element
+/**
+ \param value The value to be converted.
+ \param output The output XML element.
+*/
+template <class T> void writeStruc(const T& value, XmlElement& output);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//------------------------------ implementation -------------------------------------
+namespace impl_2384343
+{
+ZEN_INIT_DETECT_MEMBER_TYPE(value_type);
+ZEN_INIT_DETECT_MEMBER_TYPE(iterator);
+ZEN_INIT_DETECT_MEMBER_TYPE(const_iterator);
+
+ZEN_INIT_DETECT_MEMBER(begin) //
+ZEN_INIT_DETECT_MEMBER(end) //we don't know the exact declaration of the member attribute: may be in a base class!
+ZEN_INIT_DETECT_MEMBER(insert) //
+}
+
+template <typename T>
+struct IsStlContainer :
+ StaticBool<
+ impl_2384343::HasMemberType_value_type <T>::value&&
+ impl_2384343::HasMemberType_iterator <T>::value&&
+ impl_2384343::HasMemberType_const_iterator<T>::value&&
+ impl_2384343::HasMember_begin <T>::value&&
+ impl_2384343::HasMember_end <T>::value&&
+ impl_2384343::HasMember_insert <T>::value> {};
+
+
+namespace impl_2384343
+{
+ZEN_INIT_DETECT_MEMBER_TYPE(first_type);
+ZEN_INIT_DETECT_MEMBER_TYPE(second_type);
+
+ZEN_INIT_DETECT_MEMBER(first) //we don't know the exact declaration of the member attribute: may be in a base class!
+ZEN_INIT_DETECT_MEMBER(second) //
+}
+
+template <typename T>
+struct IsStlPair :
+ StaticBool<
+ impl_2384343::HasMemberType_first_type <T>::value&&
+ impl_2384343::HasMemberType_second_type<T>::value&&
+ impl_2384343::HasMember_first <T>::value&&
+ impl_2384343::HasMember_second <T>::value> {};
+
+//######################################################################################
+
+//Conversion from arbitrary types to an XML element
+enum ValueType
+{
+ VALUE_TYPE_STL_CONTAINER,
+ VALUE_TYPE_STL_PAIR,
+ VALUE_TYPE_OTHER,
+};
+
+template <class T>
+struct GetValueType : StaticEnum<ValueType,
+ GetTextType<T>::value != TEXT_TYPE_OTHER ? VALUE_TYPE_OTHER : //some string classes are also STL containers, so check this first
+ IsStlContainer<T>::value ? VALUE_TYPE_STL_CONTAINER :
+ IsStlPair<T>::value ? VALUE_TYPE_STL_PAIR :
+ VALUE_TYPE_OTHER> {};
+
+
+template <class T, ValueType type>
+struct ConvertElement;
+/* -> expected interface
+{
+ void writeStruc(const T& value, XmlElement& output) const;
+ bool readStruc(const XmlElement& input, T& value) const;
+};
+*/
+
+
+//partial specialization: handle conversion for all STL-container types!
+template <class T>
+struct ConvertElement<T, VALUE_TYPE_STL_CONTAINER>
+{
+ void writeStruc(const T& value, XmlElement& output) const
+ {
+ for (const typename T::value_type& childVal : value)
+ {
+ XmlElement& newChild = output.addChild("Item");
+ zen::writeStruc(childVal, newChild);
+ }
+ }
+ bool readStruc(const XmlElement& input, T& value) const
+ {
+ bool success = true;
+ value.clear();
+
+ auto itPair = input.getChildren("Item");
+ for (auto it = itPair.first; it != itPair.second; ++it)
+ {
+ typename T::value_type childVal; //MSVC 2010 bug: cannot put this into a lambda body
+ if (zen::readStruc(*it, childVal))
+ value.insert(value.end(), childVal);
+ else
+ success = false;
+ }
+ return success;
+ }
+};
+
+
+//partial specialization: handle conversion for std::pair
+template <class T>
+struct ConvertElement<T, VALUE_TYPE_STL_PAIR>
+{
+ void writeStruc(const T& value, XmlElement& output) const
+ {
+ XmlElement& child1 = output.addChild("one"); //don't use "1st/2nd", this will confuse a few pedantic XML parsers
+ zen::writeStruc(value.first, child1);
+
+ XmlElement& child2 = output.addChild("two");
+ zen::writeStruc(value.second, child2);
+ }
+ bool readStruc(const XmlElement& input, T& value) const
+ {
+ bool success = true;
+ const XmlElement* child1 = input.getChild("one");
+ if (!child1 || !zen::readStruc(*child1, value.first))
+ success = false;
+
+ const XmlElement* child2 = input.getChild("two");
+ if (!child2 || !zen::readStruc(*child2, value.second))
+ success = false;
+
+ return success;
+ }
+};
+
+
+//partial specialization: not a pure structured type, try text conversion (thereby respect user specializations of writeText()/readText())
+template <class T>
+struct ConvertElement<T, VALUE_TYPE_OTHER>
+{
+ void writeStruc(const T& value, XmlElement& output) const
+ {
+ std::string tmp;
+ writeText(value, tmp);
+ output.setValue(tmp);
+ }
+ bool readStruc(const XmlElement& input, T& value) const
+ {
+ std::string rawStr;
+ input.getValue(rawStr);
+ return readText(rawStr, value);
+ }
+};
+
+
+template <class T> inline
+void writeStruc(const T& value, XmlElement& output)
+{
+ ConvertElement<T, GetValueType<T>::value>().writeStruc(value, output);
+}
+
+
+template <class T> inline
+bool readStruc(const XmlElement& input, T& value)
+{
+ return ConvertElement<T, GetValueType<T>::value>().readStruc(input, value);
+}
+}
+
+#endif //CVRT_STRUC_H_018727409908342709743
bgstack15