summaryrefslogtreecommitdiff
path: root/zenxml/cvrt_struc.h
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:23:19 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:23:19 +0200
commit0887aee8c54d0ed51bb2031431e2bcdafebb4c6e (patch)
tree69537ceb9787bb25ac363cc4e6cdaf0804d78363 /zenxml/cvrt_struc.h
parent5.12 (diff)
downloadFreeFileSync-0887aee8c54d0ed51bb2031431e2bcdafebb4c6e.tar.gz
FreeFileSync-0887aee8c54d0ed51bb2031431e2bcdafebb4c6e.tar.bz2
FreeFileSync-0887aee8c54d0ed51bb2031431e2bcdafebb4c6e.zip
5.13
Diffstat (limited to 'zenxml/cvrt_struc.h')
-rw-r--r--zenxml/cvrt_struc.h218
1 files changed, 218 insertions, 0 deletions
diff --git a/zenxml/cvrt_struc.h b/zenxml/cvrt_struc.h
new file mode 100644
index 00000000..5f7f4ad1
--- /dev/null
+++ b/zenxml/cvrt_struc.h
@@ -0,0 +1,218 @@
+// **************************************************************************
+// * This file is part of the zenXML project. It is distributed under the *
+// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt *
+// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
+// **************************************************************************
+
+#ifndef ZEN_XML_CONVERT_STRUC_HEADER_018727409908342709743
+#define ZEN_XML_CONVERT_STRUC_HEADER_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
+ {
+ std::for_each(value.begin(), value.end(),
+ [&](const typename T::value_type & childVal)
+ {
+ XmlElement& newChild = output.addChild("Item");
+ zen::writeStruc(childVal, newChild);
+ });
+ }
+ bool readStruc(const XmlElement& input, T& value) const
+ {
+ bool success = true;
+ value.clear();
+
+ auto iterPair = input.getChildren("Item");
+ for (auto iter = iterPair.first; iter != iterPair.second; ++iter)
+ {
+ typename T::value_type childVal; //MSVC 2010 bug: cannot put this into a lambda body
+ if (zen::readStruc(*iter, 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 //ZEN_XML_CONVERT_STRUC_HEADER_018727409908342709743
bgstack15