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