1 #include "Core.h"
2 
3 namespace Upp {
4 
5 template<>
Xmlize(XmlIO & xml,String & var)6 void Xmlize(XmlIO& xml, String& var)
7 {
8 	if(xml.IsLoading()) {
9 		for(int i = 0; i < xml->GetCount(); i++)
10 			if(xml->Node(i).IsText()) {
11 				var = xml->Node(i).GetText();
12 				return;
13 			}
14 		var.Clear();
15 	}
16 	else {
17 		for(int i = 0; i < xml->GetCount(); i++)
18 			if(xml->Node(i).IsText()) {
19 				xml->At(i).CreateText(var);
20 				return;
21 			}
22 		xml->Add().CreateText(var);
23 	}
24 }
25 
26 template<>
Xmlize(XmlIO & xml,WString & var)27 void Xmlize(XmlIO& xml, WString& var)
28 {
29 	String h;
30 	if(xml.IsStoring())
31 		h = ToUtf8(var);
32 	Xmlize(xml, h);
33 	if(xml.IsLoading())
34 		var = FromUtf8(h);
35 }
36 
XmlAttrLoad(WString & var,const String & text)37 template<> void XmlAttrLoad(WString& var, const String& text)
38 {
39 	var = FromUtf8(text);
40 }
41 
XmlAttrStore(const WString & var)42 template<> String XmlAttrStore(const WString& var)
43 {
44 	return ToUtf8(var);
45 }
46 
XmlAttrLoad(int & var,const String & text)47 template<> void XmlAttrLoad(int& var, const String& text)
48 {
49 	var = ScanInt(text);
50 }
51 
XmlAttrStore(const int & var)52 template<> String XmlAttrStore(const int& var)
53 {
54 	return AsString(var);
55 }
56 
XmlAttrLoad(dword & var,const String & text)57 template<> void   XmlAttrLoad(dword& var, const String& text)
58 {
59 	CParser p(text);
60 	var = p.IsNumber() ? p.ReadNumber() : 0;
61 }
62 
XmlAttrStore(const double & var)63 template<> String XmlAttrStore(const double& var)
64 {
65 	return AsString(var);
66 }
67 
XmlAttrLoad(double & var,const String & text)68 template<> void XmlAttrLoad(double& var, const String& text)
69 {
70 	var = ScanDouble(text);
71 }
72 
XmlAttrStore(const dword & var)73 template<> String XmlAttrStore(const dword& var)
74 {
75 	return AsString(var);
76 }
77 
XmlAttrLoad(bool & var,const String & text)78 template<> void XmlAttrLoad(bool& var, const String& text)
79 {
80 	var = text == "1";
81 }
82 
XmlAttrStore(const bool & var)83 template<> String XmlAttrStore(const bool& var)
84 {
85 	return var ? "1" : "0";
86 }
87 
XmlAttrLoad(int16 & var,const String & text)88 template<> void XmlAttrLoad(int16& var, const String& text) {
89 	var = ScanInt(text);
90 }
91 
XmlAttrStore(const int16 & var)92 template<> String XmlAttrStore(const int16& var) {
93 	return AsString(var);
94 }
95 
XmlAttrLoad(int64 & var,const String & text)96 template<> void XmlAttrLoad(int64& var, const String& text) {
97 	var = ScanInt64(text);
98 }
99 
XmlAttrStore(const int64 & var)100 template<> String XmlAttrStore(const int64& var) {
101 	return AsString(var);
102 }
103 
XmlAttrLoad(byte & var,const String & text)104 template<> void XmlAttrLoad(byte& var, const String& text) {
105 	var = ScanInt(text);
106 }
107 
XmlAttrStore(const byte & var)108 template<> String XmlAttrStore(const byte& var) {
109 	return AsString((int)var);
110 }
111 
XmlAttrLoad(Date & var,const String & text)112 template<> void XmlAttrLoad(Date& var, const String& text) {
113 	if(text.GetCount() > 6) {
114 		var.year = ScanInt(text.Left(4));
115 		var.month = ScanInt(text.Mid(4, 2));
116 		var.day = ScanInt(text.Mid(6));
117 		if(var.IsValid())
118 			return;
119 	}
120 	var = Null;
121 }
122 
XmlAttrStore(const Date & var)123 template<> String XmlAttrStore(const Date& var) {
124 	return Format("%04d%02d%02d", var.year, var.month, var.day);
125 }
126 
XmlAttrLoad(Time & var,const String & text)127 template<> void XmlAttrLoad(Time& var, const String& text) {
128 	if(text.GetCount() > 15) {
129 		var.year = ScanInt(text.Left(4));
130 		var.month = ScanInt(text.Mid(4, 2));
131 		var.day = ScanInt(text.Mid(6, 2));
132 		var.hour = ScanInt(text.Mid(9, 2));
133 		var.minute = ScanInt(text.Mid(12, 2));
134 		var.second = ScanInt(text.Mid(15));
135 		if(var.IsValid())
136 			return;
137 	}
138 	var = Null;
139 }
140 
XmlAttrStore(const Time & var)141 template<> String XmlAttrStore(const Time& var) {
142 	return Format("%04d%02d%02d`T%02d`:%02d`:%02d", var.year, var.month, var.day, var.hour, var.minute, var.second);
143 }
144 
145 #define VALUE_XMLIZE(type) template <> void Xmlize(XmlIO& xml, type& var) { xml.Attr("value", var); }
146 
147 VALUE_XMLIZE(int);
148 VALUE_XMLIZE(dword);
149 VALUE_XMLIZE(double);
150 VALUE_XMLIZE(bool);
151 VALUE_XMLIZE(int16);
152 VALUE_XMLIZE(int64);
153 VALUE_XMLIZE(byte);
154 VALUE_XMLIZE(Time);
155 VALUE_XMLIZE(Date);
156 
XmlizeLangAttr(XmlIO & xml,int & lang,const char * id)157 void XmlizeLangAttr(XmlIO& xml, int& lang, const char *id)
158 {
159 	String l;
160 	if(xml.IsStoring())
161 		l = LNGAsText(lang);
162 	xml.Attr(id, l);
163 	if(xml.IsLoading() && !IsNull(l))
164 		lang = LNGFromText(l);
165 }
166 
XmlizeLang(XmlIO & xml,const char * tag,int & lang,const char * id)167 void XmlizeLang(XmlIO& xml, const char *tag, int& lang, const char *id)
168 {
169 	XmlIO n(xml, tag);
170 	XmlizeLangAttr(n, lang, id);
171 }
172 
DoStoreAsXML(Event<XmlIO> xmlize,const char * name)173 String DoStoreAsXML(Event<XmlIO> xmlize, const char *name)
174 {
175 	String n = Filter(name ? name : "app", CharFilterAlpha);
176 	XmlNode node;
177 	xmlize(XmlIO(node(n), false, Value()));
178 	return AsXML(node);
179 }
180 
LoadFromXML0(Event<XmlIO> xmlize,const String & xml)181 bool LoadFromXML0(Event<XmlIO> xmlize, const String& xml)
182 {
183 	XmlNode node = ParseXML(xml);
184 	if(node.GetCount() == 0)
185 		return false;
186 	for(int i = 0; i < node.GetCount(); i++)
187 		if(node.Node(i).IsTag()) {
188 			Value dummy;
189 			xmlize(XmlIO(node.At(i), true, dummy));
190 			break;
191 		}
192 	return true;
193 }
194 
DoLoadFromXML(Event<XmlIO> xmlize,const String & xml)195 bool DoLoadFromXML(Event<XmlIO> xmlize, const String& xml)
196 {
197 	try {
198 		return LoadFromXML0(xmlize, xml);
199 	}
200 	catch(ValueTypeError) {}
201 	catch(XmlError) {}
202 	return false;
203 }
204 
DoTryLoadFromXML(Event<XmlIO> xmlize,const String & xml)205 bool DoTryLoadFromXML(Event<XmlIO> xmlize, const String& xml)
206 {
207 	return LoadFromXML0(xmlize, xml);
208 }
209 
sXMLFile(const char * file)210 static String sXMLFile(const char *file)
211 {
212 	return file ? String(file) : ConfigFile(GetExeTitle() + ".xml");
213 }
214 
StoreAsXMLFile(Event<XmlIO> xmlize,const char * name,const char * file)215 bool StoreAsXMLFile(Event<XmlIO> xmlize, const char *name, const char *file)
216 {
217 	return SaveFile(sXMLFile(file), DoStoreAsXML(xmlize, name ? (String)name : GetExeTitle()));
218 }
219 
LoadFromXMLFile(Event<XmlIO> xmlize,const char * file)220 bool LoadFromXMLFile(Event<XmlIO> xmlize, const char *file)
221 {
222 	return DoLoadFromXML(xmlize, LoadFile(sXMLFile(file)));
223 }
224 
TryLoadFromXMLFile(Event<XmlIO> xmlize,const char * file)225 bool TryLoadFromXMLFile(Event<XmlIO> xmlize, const char *file)
226 {
227 	return DoTryLoadFromXML(xmlize, LoadFile(sXMLFile(file)));
228 }
229 
StoreJsonValue(XmlIO & xio,const Value & v)230 void StoreJsonValue(XmlIO& xio, const Value& v)
231 {
232 	if(v.GetType() == VALUEMAP_V) {
233 		ValueMap m = v;
234 		ValueArray va = m.GetValues();
235 		for(int i = 0; i < m.GetCount(); i++) {
236 			Value h = m.GetValue(i);
237 			XmlIO io = xio.Add((String)m.GetKey(i));
238 			StoreJsonValue(io, h);
239 		}
240 		return;
241 	}
242 	else
243 	if(v.GetType() == VALUEARRAY_V) {
244 		ValueArray va = v;
245 		for(int i = 0; i < va.GetCount(); i++) {
246 			XmlIO io = xio.Add("item");
247 			Value h = va[i];
248 			StoreJsonValue(io, h);
249 		}
250 	}
251 	else
252 	if(v.GetType() == BOOL_V) {
253 		bool b = v;
254 		Xmlize(xio, b);
255 	}
256 	else
257 	if(IsNumber(v)) {
258 		double h = v;
259 		Xmlize(xio, h);
260 		return;
261 	}
262 	else
263 	if(IsString(v)) {
264 		String h = v;
265 		Xmlize(xio, h);
266 	}
267 	else
268 	if(v.Is<Date>()) {
269 		Date h = v;
270 		Xmlize(xio, h);
271 	}
272 	else
273 	if(v.Is<Time>()) {
274 		Time h = v;
275 		Xmlize(xio, h);
276 	}
277 	else
278 		NEVER();
279 }
280 
LoadJsonValue(const XmlNode & n)281 Value LoadJsonValue(const XmlNode& n)
282 {
283 	String h = n.Attr("value");
284 	if(h.GetCount())
285 		return ScanDouble(h);
286 	ValueMap m;
287 	String text;
288 	for(int i = 0; i < n.GetCount(); i++)
289 		if(n[i].IsTag())
290 			m.Add(n[i].GetTag(), LoadJsonValue(n[i]));
291 		else
292 			return n[i].GetText();
293 	return m;
294 }
295 
296 }
297