1 class XmlIO;
2 
3 template <class T>
XmlAttrLoad(T & var,const String & text)4 void XmlAttrLoad(T& var, const String& text)
5 {
6 	var.XmlAttrLoad(text);
7 }
8 
9 template <class T>
XmlAttrStore(const T & var)10 String XmlAttrStore(const T& var)
11 {
12 	return var.XmlAttrStore();
13 }
14 
15 class XmlIO {
16 	XmlNode& node;
17 	bool     loading;
18 	Value    userdata;
19 
20 public:
IsLoading()21 	bool IsLoading() const            { return loading; }
IsStoring()22 	bool IsStoring() const            { return !loading; }
23 
Node()24 	XmlNode& Node()                   { return node; }
Node()25 	const XmlNode& Node() const       { return node; }
26 
27 	XmlNode *operator->()             { return &node; }
28 
GetAttr(const char * id)29 	String GetAttr(const char *id)                    { return node.Attr(id); }
SetAttr(const char * id,const String & val)30 	void   SetAttr(const char *id, const String& val) { node.SetAttr(id, val); }
31 
32 	template <class T> XmlIO operator()(const char *tag, T& var);
33 	template <class T> XmlIO List(const char *tag, const char *itemtag, T& var);
34 	template <class T, class X> XmlIO Var(const char *tag, T& var, X var_xmlize);
35 	template <class T, class X> XmlIO Array(const char *tag, T& var, X item_xmlize, const char *itemtag = "item");
36 
37 	template <class T, class D> XmlIO operator()(const char *tag, T& var, const D& def);
38 	template <class T, class D> XmlIO List(const char *tag, const char *itemtag, T& var, const D& def);
39 
Attr(const char * id,T & var)40 	template <class T> XmlIO Attr(const char *id, T& var) {
41 		if(IsLoading())
42 			XmlAttrLoad(var, node.Attr(id));
43 		else
44 			node.SetAttr(id, XmlAttrStore(var));
45 		return *this;
46 	}
47 
Attr(const char * id,T & var,const D & def)48 	template <class T, class D> XmlIO Attr(const char *id, T& var, const D& def) {
49 		if(IsLoading())
50 		    if(IsNull(node.Attr(id)))
51 				var = def;
52 		    else
53 				XmlAttrLoad(var, node.Attr(id));
54 		else
55 		if(var != def)
56 			node.SetAttr(id, XmlAttrStore(var));
57 		return *this;
58 	}
59 
At(int i)60 	XmlIO At(int i)                                    { XmlIO m(node.At(i), IsLoading(), userdata); return m; }
Add()61 	XmlIO Add()                                        { XmlIO m(node.Add(), IsLoading(), userdata); return m; }
Add(const char * id)62 	XmlIO Add(const char *id)                          { XmlIO m(node.Add(id), IsLoading(), userdata); return m; }
GetAdd(const char * id)63 	XmlIO GetAdd(const char *id)                       { XmlIO m(node.GetAdd(id), IsLoading(), userdata); return m; }
64 
SetUserData(const Value & v)65 	void  SetUserData(const Value& v)                  { userdata = v; }
GetUserData()66 	Value GetUserData() const                          { return userdata; }
67 
XmlIO(XmlNode & xml,bool loading,const Value & userdata)68 	XmlIO(XmlNode& xml, bool loading, const Value& userdata) : node(xml), loading(loading), userdata(userdata) {}
XmlIO(XmlNode & xml,bool loading)69 	XmlIO(XmlNode& xml, bool loading) : node(xml), loading(loading) {}
XmlIO(XmlIO xml,const char * tag)70 	XmlIO(XmlIO xml, const char *tag) : node(xml.node.GetAdd(tag)), loading(xml.loading), userdata(xml.userdata) {}
71 };
72 
XmlAttrLoad(String & var,const String & text)73 template<> inline void XmlAttrLoad(String& var, const String& text) { var = text; }
XmlAttrStore(const String & var)74 template<> inline String XmlAttrStore(const String& var)            { return var; }
75 
76 template<> void XmlAttrLoad(WString& var, const String& text);
77 template<> String XmlAttrStore(const WString& var);
78 template<> void XmlAttrLoad(int& var, const String& text);
79 template<> String XmlAttrStore(const int& var);
80 template<> void XmlAttrLoad(dword& var, const String& text);
81 template<> String XmlAttrStore(const dword& var);
82 template<> void XmlAttrLoad(double& var, const String& text);
83 template<> String XmlAttrStore(const double& var);
84 template<> void XmlAttrLoad(bool& var, const String& text);
85 template<> String XmlAttrStore(const bool& var);
86 template <> void XmlAttrLoad(int16& var, const String& text);
87 template <> String XmlAttrStore(const int16& var);
88 template <> void XmlAttrLoad(int64& var, const String& text);
89 template <> String XmlAttrStore(const int64& var);
90 template <> void XmlAttrLoad(byte& var, const String& text);
91 template <> String XmlAttrStore(const byte& var);
92 template <> void XmlAttrLoad(Date& var, const String& text);
93 template <> String XmlAttrStore(const Date& var);
94 template <> void XmlAttrLoad(Time& var, const String& text);
95 template <> String XmlAttrStore(const Time& var);
96 
97 template<> void Xmlize(XmlIO& xml, String& var);
98 template<> void Xmlize(XmlIO& xml, WString& var);
99 template<> void Xmlize(XmlIO& xml, int& var);
100 template<> void Xmlize(XmlIO& xml, dword& var);
101 template<> void Xmlize(XmlIO& xml, double& var);
102 template<> void Xmlize(XmlIO& xml, bool& var);
103 template<> void Xmlize(XmlIO& xml, Date& var);
104 template<> void Xmlize(XmlIO& xml, Time& var);
105 template<> void Xmlize(XmlIO& xml, int16& var);
106 template<> void Xmlize(XmlIO& xml, int64& var);
107 template<> void Xmlize(XmlIO& xml, byte& var);
108 
109 void XmlizeLangAttr(XmlIO& xml, int& lang, const char *id = "lang");
110 void XmlizeLang(XmlIO& xml, const char *tag, int& lang, const char *id = "id");
111 
112 template <class T>
Xmlize(XmlIO & xml,T & var)113 void Xmlize(XmlIO& xml, T& var)
114 {
115 	var.Xmlize(xml);
116 }
117 
118 template <class T>
Xmlize(XmlIO & xml,const char * itemtag,T & var)119 void Xmlize(XmlIO& xml, const char* itemtag, T& var)
120 {
121 	var.Xmlize(xml, itemtag);
122 }
123 
124 template <class T, class X>
125 void XmlizeContainer(XmlIO& xml, const char *tag, T& data, X item_xmlize);
126 
127 template<class T>
128 void XmlizeContainer(XmlIO& xml, const char *tag, T& data);
129 
130 template<class K, class V, class T>
131 void XmlizeMap(XmlIO& xml, const char *keytag, const char *valuetag, T& data);
132 
133 template<class K, class V, class T>
134 void XmlizeSortedMap(XmlIO& xml, const char *keytag, const char *valuetag, T& data);
135 
136 template<class K, class T>
137 void XmlizeIndex(XmlIO& xml, const char *keytag, T& data);
138 
139 template<class T>
XmlizeStore(XmlIO & xml,const T & data)140 void XmlizeStore(XmlIO& xml, const T& data)
141 {
142 	ASSERT(xml.IsStoring());
143 	Xmlize(xml, const_cast<T&>(data));
144 }
145 
146 template <class T>
147 struct ParamHelper__ {
148 	T&   data;
InvokeParamHelper__149 	void Invoke(XmlIO xml) {
150 		Xmlize(xml, data);
151 	}
152 
ParamHelper__ParamHelper__153 	ParamHelper__(T& data) : data(data) {}
154 };
155 
156 String DoStoreAsXML(Event<XmlIO> xmlize, const char *name);
157 bool   DoLoadFromXML(Event<XmlIO> xmlize, const String& xml);
158 bool   DoTryLoadFromXML(Event<XmlIO> xmlize, const String& xml);
159 
160 template <class T>
161 String StoreAsXML(const T& data, const char *name = NULL)
162 {
163 	ParamHelper__<T> p(const_cast<T &>(data));
164 	return DoStoreAsXML([&](XmlIO io) { Xmlize(io, const_cast<T &>(data)); }, name);
165 }
166 
167 template <class T>
LoadFromXML(T & data,const String & xml)168 bool LoadFromXML(T& data, const String& xml)
169 {
170 	ParamHelper__<T> p(data);
171 	return DoLoadFromXML(callback(&p, &ParamHelper__<T>::Invoke), xml);
172 }
173 
174 template <class T>
TryLoadFromXML(T & data,const String & xml)175 bool TryLoadFromXML(T& data, const String& xml)
176 {
177 	ParamHelper__<T> p(data);
178 	return DoTryLoadFromXML(callback(&p, &ParamHelper__<T>::Invoke), xml);
179 }
180 
181 bool StoreAsXMLFile(Event<XmlIO> xmlize, const char *name = NULL, const char *file = NULL);
182 bool LoadFromXMLFile(Event<XmlIO> xmlize, const char *file = NULL);
183 bool TryLoadFromXMLFile(Event<XmlIO> xmlize, const char *file = NULL);
184 
185 template <class T>
186 bool StoreAsXMLFile(T& data, const char *name = NULL, const char *file = NULL)
187 {
188 	ParamHelper__<T> p(data);
189 	return StoreAsXMLFile(callback(&p, &ParamHelper__<T>::Invoke), name, file);
190 }
191 
192 template <class T>
193 bool LoadFromXMLFile(T& data, const char *file = NULL)
194 {
195 	ParamHelper__<T> p(data);
196 	return LoadFromXMLFile(callback(&p, &ParamHelper__<T>::Invoke), file);
197 }
198 
199 template <class T>
200 bool TryLoadFromXMLFile(T& data, const char *file = NULL)
201 {
202 	ParamHelper__<T> p(data);
203 	return TryLoadFromXMLFile(callback(&p, &ParamHelper__<T>::Invoke), file);
204 }
205 
206 template <class T>
XmlizeBySerialize(XmlIO & xio,T & x)207 void XmlizeBySerialize(XmlIO& xio, T& x)
208 {
209 	String h;
210 	if(xio.IsStoring())
211 		h = HexString(StoreAsString(x));
212 	xio.Attr("data", h);
213 	if(xio.IsLoading())
214 		try {
215 			LoadFromString(x, ScanHexString(h));
216 		}
217 		catch(LoadingError) {
218 			throw XmlError("xmlize by serialize error");
219 		}
220 }
221 
222 void  StoreJsonValue(XmlIO& xio, const Value& v);
223 Value LoadJsonValue(const XmlNode& n);
224 
225 template <class T>
XmlizeByJsonize(XmlIO & xio,T & x)226 void XmlizeByJsonize(XmlIO& xio, T& x)
227 {
228 	if(xio.IsStoring())
229 		StoreJsonValue(xio, StoreAsJsonValue(x));
230 	else {
231 		try {
232 			LoadFromJsonValue(x, LoadJsonValue(xio.Node()));
233 		}
234 		catch(JsonizeError e) {
235 			throw XmlError("xmlize by jsonize error: " + e);
236 		}
237 	}
238 }
239 
240 #include "Xmlize.hpp"