class XmlIO; template void XmlAttrLoad(T& var, const String& text) { var.XmlAttrLoad(text); } template String XmlAttrStore(const T& var) { return var.XmlAttrStore(); } class XmlIO { XmlNode& node; bool loading; Value userdata; public: bool IsLoading() const { return loading; } bool IsStoring() const { return !loading; } XmlNode& Node() { return node; } const XmlNode& Node() const { return node; } XmlNode *operator->() { return &node; } String GetAttr(const char *id) { return node.Attr(id); } void SetAttr(const char *id, const String& val) { node.SetAttr(id, val); } template XmlIO operator()(const char *tag, T& var); template XmlIO List(const char *tag, const char *itemtag, T& var); template XmlIO Var(const char *tag, T& var, X var_xmlize); template XmlIO Array(const char *tag, T& var, X item_xmlize, const char *itemtag = "item"); template XmlIO operator()(const char *tag, T& var, const D& def); template XmlIO List(const char *tag, const char *itemtag, T& var, const D& def); template XmlIO Attr(const char *id, T& var) { if(IsLoading()) XmlAttrLoad(var, node.Attr(id)); else node.SetAttr(id, XmlAttrStore(var)); return *this; } template XmlIO Attr(const char *id, T& var, const D& def) { if(IsLoading()) if(IsNull(node.Attr(id))) var = def; else XmlAttrLoad(var, node.Attr(id)); else if(var != def) node.SetAttr(id, XmlAttrStore(var)); return *this; } XmlIO At(int i) { XmlIO m(node.At(i), IsLoading(), userdata); return m; } XmlIO Add() { XmlIO m(node.Add(), IsLoading(), userdata); return m; } XmlIO Add(const char *id) { XmlIO m(node.Add(id), IsLoading(), userdata); return m; } XmlIO GetAdd(const char *id) { XmlIO m(node.GetAdd(id), IsLoading(), userdata); return m; } void SetUserData(const Value& v) { userdata = v; } Value GetUserData() const { return userdata; } XmlIO(XmlNode& xml, bool loading, const Value& userdata) : node(xml), loading(loading), userdata(userdata) {} XmlIO(XmlNode& xml, bool loading) : node(xml), loading(loading) {} XmlIO(XmlIO xml, const char *tag) : node(xml.node.GetAdd(tag)), loading(xml.loading), userdata(xml.userdata) {} }; template<> inline void XmlAttrLoad(String& var, const String& text) { var = text; } template<> inline String XmlAttrStore(const String& var) { return var; } template<> void XmlAttrLoad(WString& var, const String& text); template<> String XmlAttrStore(const WString& var); template<> void XmlAttrLoad(int& var, const String& text); template<> String XmlAttrStore(const int& var); template<> void XmlAttrLoad(dword& var, const String& text); template<> String XmlAttrStore(const dword& var); template<> void XmlAttrLoad(double& var, const String& text); template<> String XmlAttrStore(const double& var); template<> void XmlAttrLoad(float& var, const String& text); template<> String XmlAttrStore(const float& var); template<> void XmlAttrLoad(bool& var, const String& text); template<> String XmlAttrStore(const bool& var); template <> void XmlAttrLoad(int16& var, const String& text); template <> String XmlAttrStore(const int16& var); template <> void XmlAttrLoad(int64& var, const String& text); template <> String XmlAttrStore(const int64& var); template <> void XmlAttrLoad(byte& var, const String& text); template <> String XmlAttrStore(const byte& var); template <> void XmlAttrLoad(Date& var, const String& text); template <> String XmlAttrStore(const Date& var); template <> void XmlAttrLoad(Time& var, const String& text); template <> String XmlAttrStore(const Time& var); template<> void Xmlize(XmlIO& xml, String& var); template<> void Xmlize(XmlIO& xml, WString& var); template<> void Xmlize(XmlIO& xml, int& var); template<> void Xmlize(XmlIO& xml, dword& var); template<> void Xmlize(XmlIO& xml, double& var); template<> void Xmlize(XmlIO& xml, float& var); template<> void Xmlize(XmlIO& xml, bool& var); template<> void Xmlize(XmlIO& xml, Date& var); template<> void Xmlize(XmlIO& xml, Time& var); template<> void Xmlize(XmlIO& xml, int16& var); template<> void Xmlize(XmlIO& xml, int64& var); template<> void Xmlize(XmlIO& xml, byte& var); void XmlizeLangAttr(XmlIO& xml, int& lang, const char *id = "lang"); void XmlizeLang(XmlIO& xml, const char *tag, int& lang, const char *id = "id"); template void Xmlize(XmlIO& xml, T& var) { var.Xmlize(xml); } template void Xmlize(XmlIO& xml, const char* itemtag, T& var) { var.Xmlize(xml, itemtag); } template void XmlizeContainer(XmlIO& xml, const char *tag, T& data, X item_xmlize); template void XmlizeContainer(XmlIO& xml, const char *tag, T& data); template void XmlizeMap(XmlIO& xml, const char *keytag, const char *valuetag, T& data); template void XmlizeSortedMap(XmlIO& xml, const char *keytag, const char *valuetag, T& data); template void XmlizeIndex(XmlIO& xml, const char *keytag, T& data); template void XmlizeStore(XmlIO& xml, const T& data) { ASSERT(xml.IsStoring()); Xmlize(xml, const_cast(data)); } template struct ParamHelper__ { T& data; void Invoke(XmlIO xml) { Xmlize(xml, data); } ParamHelper__(T& data) : data(data) {} }; String DoStoreAsXML(Event xmlize, const char *name); bool DoLoadFromXML(Event xmlize, const String& xml); bool DoTryLoadFromXML(Event xmlize, const String& xml); template String StoreAsXML(const T& data, const char *name = NULL) { ParamHelper__ p(const_cast(data)); return DoStoreAsXML([&](XmlIO io) { Xmlize(io, const_cast(data)); }, name); } template bool LoadFromXML(T& data, const String& xml) { ParamHelper__ p(data); return DoLoadFromXML(callback(&p, &ParamHelper__::Invoke), xml); } template bool TryLoadFromXML(T& data, const String& xml) { ParamHelper__ p(data); return DoTryLoadFromXML(callback(&p, &ParamHelper__::Invoke), xml); } bool StoreAsXMLFile(Event xmlize, const char *name = NULL, const char *file = NULL); bool LoadFromXMLFile(Event xmlize, const char *file = NULL); bool TryLoadFromXMLFile(Event xmlize, const char *file = NULL); template bool StoreAsXMLFile(T& data, const char *name = NULL, const char *file = NULL) { ParamHelper__ p(data); return StoreAsXMLFile(callback(&p, &ParamHelper__::Invoke), name, file); } template bool LoadFromXMLFile(T& data, const char *file = NULL) { ParamHelper__ p(data); return LoadFromXMLFile(callback(&p, &ParamHelper__::Invoke), file); } template bool TryLoadFromXMLFile(T& data, const char *file = NULL) { ParamHelper__ p(data); return TryLoadFromXMLFile(callback(&p, &ParamHelper__::Invoke), file); } template void XmlizeBySerialize(XmlIO& xio, T& x) { String h; if(xio.IsStoring()) h = HexString(StoreAsString(x)); xio.Attr("data", h); if(xio.IsLoading()) try { LoadFromString(x, ScanHexString(h)); } catch(LoadingError) { throw XmlError("xmlize by serialize error"); } } void StoreJsonValue(XmlIO& xio, const Value& v); Value LoadJsonValue(const XmlNode& n); template void XmlizeByJsonize(XmlIO& xio, T& x) { if(xio.IsStoring()) StoreJsonValue(xio, StoreAsJsonValue(x)); else { try { LoadFromJsonValue(x, LoadJsonValue(xio.Node())); } catch(JsonizeError e) { throw XmlError("xmlize by jsonize error: " + e); } } } #include "Xmlize.hpp"