]>
Commit | Line | Data |
---|---|---|
341287bf JS |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: variant.cpp | |
3 | // Purpose: wxVariant class, container for any type | |
4 | // Author: Julian Smart | |
5 | // Modified by: | |
6 | // Created: 10/09/98 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | #ifdef __GNUG__ | |
13 | #pragma implementation "variant.h" | |
14 | #endif | |
15 | ||
16 | // For compilers that support precompilation, includes "wx/wx.h". | |
17 | #include "wx/wxprec.h" | |
18 | ||
19 | #ifdef __BORLANDC__ | |
20 | #pragma hdrstop | |
21 | #endif | |
22 | ||
fbc535ff | 23 | #if wxUSE_IOSTREAMH |
03f38c58 | 24 | # include <fstream.h> |
fbc535ff | 25 | #else |
03f38c58 VZ |
26 | # include <fstream> |
27 | # ifdef _MSC_VER | |
28 | using namespace std; | |
29 | # endif | |
fbc535ff | 30 | #endif |
341287bf JS |
31 | |
32 | #include "wx/string.h" | |
33 | #include "wx/variant.h" | |
34 | ||
35 | IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject) | |
36 | ||
37 | wxVariant wxNullVariant; | |
38 | ||
39 | /* | |
40 | * wxVariantDataList | |
41 | */ | |
42 | ||
43 | class WXDLLEXPORT wxVariantDataList: public wxVariantData | |
44 | { | |
45 | DECLARE_DYNAMIC_CLASS(wxVariantDataList) | |
46 | public: | |
47 | wxVariantDataList() {} | |
48 | wxVariantDataList(const wxList& list); | |
49 | ~wxVariantDataList(); | |
50 | ||
51 | wxList& GetValue() const { return (wxList&) m_value; } | |
52 | void SetValue(const wxList& value) ; | |
53 | ||
54 | virtual void Copy(wxVariantData& data); | |
55 | virtual bool Eq(wxVariantData& data) const; | |
56 | virtual bool Write(ostream& str) const; | |
57 | virtual bool Write(wxString& str) const; | |
58 | virtual bool Read(istream& str); | |
59 | virtual bool Read(wxString& str); | |
60 | virtual wxString GetType() const { return "list"; }; | |
61 | ||
62 | void Clear(); | |
63 | ||
64 | protected: | |
65 | wxList m_value; | |
66 | }; | |
67 | ||
68 | IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData) | |
69 | ||
70 | wxVariantDataList::wxVariantDataList(const wxList& list) | |
71 | { | |
72 | SetValue(list); | |
73 | } | |
74 | ||
75 | wxVariantDataList::~wxVariantDataList() | |
76 | { | |
77 | Clear(); | |
78 | } | |
79 | ||
80 | void wxVariantDataList::SetValue(const wxList& value) | |
81 | { | |
82 | Clear(); | |
83 | wxNode* node = value.First(); | |
84 | while (node) | |
85 | { | |
86 | wxVariant* var = (wxVariant*) node->Data(); | |
87 | m_value.Append(new wxVariant(*var)); | |
88 | node = node->Next(); | |
89 | } | |
90 | } | |
91 | ||
92 | void wxVariantDataList::Clear() | |
93 | { | |
94 | wxNode* node = m_value.First(); | |
95 | while (node) | |
96 | { | |
97 | wxVariant* var = (wxVariant*) node->Data(); | |
98 | delete var; | |
99 | node = node->Next(); | |
100 | } | |
101 | m_value.Clear(); | |
102 | } | |
103 | ||
104 | void wxVariantDataList::Copy(wxVariantData& data) | |
105 | { | |
106 | wxASSERT_MSG( (data.GetType() == "list"), "wxVariantDataList::Copy: Can't copy to this type of data" ); | |
107 | ||
108 | wxVariantDataList& listData = (wxVariantDataList&) data; | |
109 | ||
110 | listData.Clear(); | |
111 | wxNode* node = m_value.First(); | |
112 | while (node) | |
113 | { | |
114 | wxVariant* var = (wxVariant*) node->Data(); | |
115 | listData.m_value.Append(new wxVariant(*var)); | |
116 | node = node->Next(); | |
117 | } | |
118 | } | |
119 | ||
120 | bool wxVariantDataList::Eq(wxVariantData& data) const | |
121 | { | |
122 | wxASSERT_MSG( (data.GetType() == "list"), "wxVariantDataList::Eq: argument mismatch" ); | |
123 | ||
124 | wxVariantDataList& listData = (wxVariantDataList&) data; | |
125 | wxNode* node1 = m_value.First(); | |
126 | wxNode* node2 = listData.GetValue().First(); | |
127 | while (node1 && node2) | |
128 | { | |
129 | wxVariant* var1 = (wxVariant*) node1->Data(); | |
130 | wxVariant* var2 = (wxVariant*) node2->Data(); | |
131 | if ((*var1) != (*var2)) | |
132 | return FALSE; | |
133 | node1 = node1->Next(); | |
134 | node2 = node2->Next(); | |
135 | } | |
136 | if (node1 || node2) return FALSE; | |
137 | return TRUE; | |
138 | } | |
139 | ||
140 | bool wxVariantDataList::Write(ostream& str) const | |
141 | { | |
142 | wxString s; | |
143 | Write(s); | |
144 | str << s; | |
145 | return TRUE; | |
146 | } | |
147 | ||
148 | bool wxVariantDataList::Write(wxString& str) const | |
149 | { | |
150 | str = ""; | |
151 | wxNode* node = m_value.First(); | |
152 | while (node) | |
153 | { | |
154 | wxVariant* var = (wxVariant*) node->Data(); | |
155 | if (node != m_value.First()) | |
156 | str += " "; | |
157 | wxString str1; | |
158 | str += var->MakeString(); | |
159 | node = node->Next(); | |
160 | } | |
161 | ||
162 | return TRUE; | |
163 | } | |
164 | ||
165 | bool wxVariantDataList::Read(istream& WXUNUSED(str)) | |
166 | { | |
167 | wxFAIL_MSG("Unimplemented"); | |
168 | // TODO | |
169 | return FALSE; | |
170 | } | |
171 | ||
172 | bool wxVariantDataList::Read(wxString& WXUNUSED(str)) | |
173 | { | |
174 | wxFAIL_MSG("Unimplemented"); | |
175 | // TODO | |
176 | return FALSE; | |
177 | } | |
178 | ||
179 | /* | |
180 | * wxVariantDataStringList | |
181 | */ | |
182 | ||
183 | class WXDLLEXPORT wxVariantDataStringList: public wxVariantData | |
184 | { | |
185 | DECLARE_DYNAMIC_CLASS(wxVariantDataStringList) | |
186 | public: | |
187 | wxVariantDataStringList() {} | |
188 | wxVariantDataStringList(const wxStringList& list) { m_value = list; } | |
189 | ||
190 | wxStringList& GetValue() const { return (wxStringList&) m_value; } | |
191 | void SetValue(const wxStringList& value); | |
192 | ||
193 | virtual void Copy(wxVariantData& data); | |
194 | virtual bool Eq(wxVariantData& data) const; | |
195 | virtual bool Write(ostream& str) const; | |
196 | virtual bool Write(wxString& str) const; | |
197 | virtual bool Read(istream& str); | |
198 | virtual bool Read(wxString& str); | |
199 | virtual wxString GetType() const { return "stringlist"; }; | |
200 | ||
201 | protected: | |
202 | wxStringList m_value; | |
203 | }; | |
204 | ||
205 | IMPLEMENT_DYNAMIC_CLASS(wxVariantDataStringList, wxVariantData) | |
206 | ||
207 | void wxVariantDataStringList::SetValue(const wxStringList& value) | |
208 | { | |
209 | m_value = value; | |
210 | } | |
211 | ||
212 | void wxVariantDataStringList::Copy(wxVariantData& data) | |
213 | { | |
214 | wxASSERT_MSG( (data.GetType() == "stringlist"), "wxVariantDataStringList::Copy: Can't copy to this type of data" ); | |
215 | ||
216 | wxVariantDataStringList& listData = (wxVariantDataStringList&) data; | |
217 | ||
218 | listData.m_value = m_value ; | |
219 | } | |
220 | ||
221 | bool wxVariantDataStringList::Eq(wxVariantData& data) const | |
222 | { | |
223 | wxASSERT_MSG( (data.GetType() == "stringlist"), "wxVariantDataStringList::Eq: argument mismatch" ); | |
224 | ||
225 | wxVariantDataStringList& listData = (wxVariantDataStringList&) data; | |
226 | wxNode* node1 = m_value.First(); | |
227 | wxNode* node2 = listData.GetValue().First(); | |
228 | while (node1 && node2) | |
229 | { | |
230 | wxString str1 ((char*) node1->Data()); | |
231 | wxString str2 ((char*) node2->Data()); | |
232 | if (str1 != str2) | |
233 | return FALSE; | |
234 | node1 = node1->Next(); | |
235 | node2 = node2->Next(); | |
236 | } | |
237 | if (node1 || node2) return FALSE; | |
238 | return TRUE; | |
239 | } | |
240 | ||
241 | bool wxVariantDataStringList::Write(ostream& str) const | |
242 | { | |
243 | wxString s; | |
244 | Write(s); | |
245 | str << s; | |
246 | return TRUE; | |
247 | } | |
248 | ||
249 | bool wxVariantDataStringList::Write(wxString& str) const | |
250 | { | |
251 | str = ""; | |
252 | wxNode* node = m_value.First(); | |
253 | while (node) | |
254 | { | |
255 | char* s = (char*) node->Data(); | |
256 | if (node != m_value.First()) | |
257 | str += " "; | |
258 | str += s; | |
259 | node = node->Next(); | |
260 | } | |
261 | ||
262 | return TRUE; | |
263 | } | |
264 | ||
265 | bool wxVariantDataStringList::Read(istream& WXUNUSED(str)) | |
266 | { | |
267 | wxFAIL_MSG("Unimplemented"); | |
268 | // TODO | |
269 | return FALSE; | |
270 | } | |
271 | ||
272 | bool wxVariantDataStringList::Read(wxString& WXUNUSED(str)) | |
273 | { | |
274 | wxFAIL_MSG("Unimplemented"); | |
275 | // TODO | |
276 | return FALSE; | |
277 | } | |
278 | ||
279 | /* | |
280 | * wxVariantDataLong | |
281 | */ | |
282 | ||
283 | class WXDLLEXPORT wxVariantDataLong: public wxVariantData | |
284 | { | |
285 | DECLARE_DYNAMIC_CLASS(wxVariantDataLong) | |
286 | public: | |
287 | wxVariantDataLong() { m_value = 0; } | |
288 | wxVariantDataLong(long value) { m_value = value; } | |
289 | ||
290 | inline long GetValue() const { return m_value; } | |
291 | inline void SetValue(long value) { m_value = value; } | |
292 | ||
293 | virtual void Copy(wxVariantData& data); | |
294 | virtual bool Eq(wxVariantData& data) const; | |
295 | virtual bool Write(ostream& str) const; | |
296 | virtual bool Write(wxString& str) const; | |
297 | virtual bool Read(istream& str); | |
298 | virtual bool Read(wxString& str); | |
299 | virtual wxString GetType() const { return "long"; }; | |
300 | ||
301 | protected: | |
302 | long m_value; | |
303 | }; | |
304 | ||
305 | IMPLEMENT_DYNAMIC_CLASS(wxVariantDataLong, wxVariantData) | |
306 | ||
307 | void wxVariantDataLong::Copy(wxVariantData& data) | |
308 | { | |
309 | wxASSERT_MSG( (data.GetType() == "long"), "wxVariantDataLong::Copy: Can't copy to this type of data" ); | |
310 | ||
311 | wxVariantDataLong& otherData = (wxVariantDataLong&) data; | |
312 | ||
313 | otherData.m_value = m_value; | |
314 | } | |
315 | ||
316 | bool wxVariantDataLong::Eq(wxVariantData& data) const | |
317 | { | |
318 | wxASSERT_MSG( (data.GetType() == "long"), "wxVariantDataLong::Eq: argument mismatch" ); | |
319 | ||
320 | wxVariantDataLong& otherData = (wxVariantDataLong&) data; | |
321 | ||
322 | return (otherData.m_value == m_value); | |
323 | } | |
324 | ||
325 | bool wxVariantDataLong::Write(ostream& str) const | |
326 | { | |
327 | wxString s; | |
328 | Write(s); | |
329 | str << s; | |
330 | return TRUE; | |
331 | } | |
332 | ||
333 | bool wxVariantDataLong::Write(wxString& str) const | |
334 | { | |
335 | str.Printf("%ld", m_value); | |
336 | return TRUE; | |
337 | } | |
338 | ||
339 | bool wxVariantDataLong::Read(istream& str) | |
340 | { | |
341 | str >> m_value; | |
342 | return TRUE; | |
343 | } | |
344 | ||
345 | bool wxVariantDataLong::Read(wxString& str) | |
346 | { | |
347 | m_value = atol((const char*) str); | |
348 | return TRUE; | |
349 | } | |
350 | ||
351 | /* | |
352 | * wxVariantDataReal | |
353 | */ | |
354 | ||
355 | class WXDLLEXPORT wxVariantDataReal: public wxVariantData | |
356 | { | |
357 | DECLARE_DYNAMIC_CLASS(wxVariantDataReal) | |
358 | public: | |
359 | wxVariantDataReal() { m_value = 0.0; } | |
360 | wxVariantDataReal(double value) { m_value = value; } | |
361 | ||
362 | inline double GetValue() const { return m_value; } | |
363 | inline void SetValue(double value) { m_value = value; } | |
364 | ||
365 | virtual void Copy(wxVariantData& data); | |
366 | virtual bool Eq(wxVariantData& data) const; | |
367 | virtual bool Write(ostream& str) const; | |
368 | virtual bool Write(wxString& str) const; | |
369 | virtual bool Read(istream& str); | |
370 | virtual bool Read(wxString& str); | |
371 | virtual wxString GetType() const { return "double"; }; | |
372 | ||
373 | protected: | |
374 | double m_value; | |
375 | }; | |
376 | ||
377 | IMPLEMENT_DYNAMIC_CLASS(wxVariantDataReal, wxVariantData) | |
378 | ||
379 | void wxVariantDataReal::Copy(wxVariantData& data) | |
380 | { | |
381 | wxASSERT_MSG( (data.GetType() == "double"), "wxVariantDataReal::Copy: Can't copy to this type of data" ); | |
382 | ||
383 | wxVariantDataReal& otherData = (wxVariantDataReal&) data; | |
384 | ||
385 | otherData.m_value = m_value; | |
386 | } | |
387 | ||
388 | bool wxVariantDataReal::Eq(wxVariantData& data) const | |
389 | { | |
390 | wxASSERT_MSG( (data.GetType() == "double"), "wxVariantDataReal::Eq: argument mismatch" ); | |
391 | ||
392 | wxVariantDataReal& otherData = (wxVariantDataReal&) data; | |
393 | ||
394 | return (otherData.m_value == m_value); | |
395 | } | |
396 | ||
397 | bool wxVariantDataReal::Write(ostream& str) const | |
398 | { | |
399 | wxString s; | |
400 | Write(s); | |
401 | str << s; | |
402 | return TRUE; | |
403 | } | |
404 | ||
405 | bool wxVariantDataReal::Write(wxString& str) const | |
406 | { | |
407 | str.Printf("%.4f", m_value); | |
408 | return TRUE; | |
409 | } | |
410 | ||
411 | bool wxVariantDataReal::Read(istream& str) | |
412 | { | |
413 | str >> m_value; | |
414 | return TRUE; | |
415 | } | |
416 | ||
417 | bool wxVariantDataReal::Read(wxString& str) | |
418 | { | |
419 | m_value = atof((const char*) str); | |
420 | return TRUE; | |
421 | } | |
422 | ||
423 | /* | |
424 | * wxVariantDataBool | |
425 | */ | |
426 | ||
427 | class WXDLLEXPORT wxVariantDataBool: public wxVariantData | |
428 | { | |
429 | DECLARE_DYNAMIC_CLASS(wxVariantDataBool) | |
430 | public: | |
431 | wxVariantDataBool() { m_value = 0; } | |
432 | wxVariantDataBool(bool value) { m_value = value; } | |
433 | ||
434 | inline bool GetValue() const { return m_value; } | |
435 | inline void SetValue(bool value) { m_value = value; } | |
436 | ||
437 | virtual void Copy(wxVariantData& data); | |
438 | virtual bool Eq(wxVariantData& data) const; | |
439 | virtual bool Write(ostream& str) const; | |
440 | virtual bool Write(wxString& str) const; | |
441 | virtual bool Read(istream& str); | |
442 | virtual bool Read(wxString& str); | |
443 | virtual wxString GetType() const { return "bool"; }; | |
444 | ||
445 | protected: | |
446 | bool m_value; | |
447 | }; | |
448 | ||
449 | IMPLEMENT_DYNAMIC_CLASS(wxVariantDataBool, wxVariantData) | |
450 | ||
451 | void wxVariantDataBool::Copy(wxVariantData& data) | |
452 | { | |
453 | wxASSERT_MSG( (data.GetType() == "bool"), "wxVariantDataBool::Copy: Can't copy to this type of data" ); | |
454 | ||
455 | wxVariantDataBool& otherData = (wxVariantDataBool&) data; | |
456 | ||
457 | otherData.m_value = m_value; | |
458 | } | |
459 | ||
460 | bool wxVariantDataBool::Eq(wxVariantData& data) const | |
461 | { | |
462 | wxASSERT_MSG( (data.GetType() == "bool"), "wxVariantDataBool::Eq: argument mismatch" ); | |
463 | ||
464 | wxVariantDataBool& otherData = (wxVariantDataBool&) data; | |
465 | ||
466 | return (otherData.m_value == m_value); | |
467 | } | |
468 | ||
469 | bool wxVariantDataBool::Write(ostream& str) const | |
470 | { | |
471 | wxString s; | |
472 | Write(s); | |
473 | str << s; | |
474 | return TRUE; | |
475 | } | |
476 | ||
477 | bool wxVariantDataBool::Write(wxString& str) const | |
478 | { | |
479 | str.Printf("%d", (int) m_value); | |
480 | return TRUE; | |
481 | } | |
482 | ||
483 | bool wxVariantDataBool::Read(istream& WXUNUSED(str)) | |
484 | { | |
485 | wxFAIL_MSG("Unimplemented"); | |
486 | // str >> (long) m_value; | |
487 | return FALSE; | |
488 | } | |
489 | ||
490 | bool wxVariantDataBool::Read(wxString& str) | |
491 | { | |
492 | m_value = (atol((const char*) str) != 0); | |
493 | return TRUE; | |
494 | } | |
495 | ||
496 | /* | |
497 | * wxVariantDataChar | |
498 | */ | |
499 | ||
500 | class WXDLLEXPORT wxVariantDataChar: public wxVariantData | |
501 | { | |
502 | DECLARE_DYNAMIC_CLASS(wxVariantDataChar) | |
503 | public: | |
504 | wxVariantDataChar() { m_value = 0; } | |
505 | wxVariantDataChar(char value) { m_value = value; } | |
506 | ||
507 | inline char GetValue() const { return m_value; } | |
508 | inline void SetValue(char value) { m_value = value; } | |
509 | ||
510 | virtual void Copy(wxVariantData& data); | |
511 | virtual bool Eq(wxVariantData& data) const; | |
512 | virtual bool Write(ostream& str) const; | |
513 | virtual bool Write(wxString& str) const; | |
514 | virtual bool Read(istream& str); | |
515 | virtual bool Read(wxString& str); | |
516 | virtual wxString GetType() const { return "char"; }; | |
517 | ||
518 | protected: | |
519 | char m_value; | |
520 | }; | |
521 | ||
522 | IMPLEMENT_DYNAMIC_CLASS(wxVariantDataChar, wxVariantData) | |
523 | ||
524 | void wxVariantDataChar::Copy(wxVariantData& data) | |
525 | { | |
526 | wxASSERT_MSG( (data.GetType() == "char"), "wxVariantDataChar::Copy: Can't copy to this type of data" ); | |
527 | ||
528 | wxVariantDataChar& otherData = (wxVariantDataChar&) data; | |
529 | ||
530 | otherData.m_value = m_value; | |
531 | } | |
532 | ||
533 | bool wxVariantDataChar::Eq(wxVariantData& data) const | |
534 | { | |
535 | wxASSERT_MSG( (data.GetType() == "char"), "wxVariantDataChar::Eq: argument mismatch" ); | |
536 | ||
537 | wxVariantDataChar& otherData = (wxVariantDataChar&) data; | |
538 | ||
539 | return (otherData.m_value == m_value); | |
540 | } | |
541 | ||
542 | bool wxVariantDataChar::Write(ostream& str) const | |
543 | { | |
544 | wxString s; | |
545 | Write(s); | |
546 | str << s; | |
547 | return TRUE; | |
548 | } | |
549 | ||
550 | bool wxVariantDataChar::Write(wxString& str) const | |
551 | { | |
552 | str.Printf("%c", m_value); | |
553 | return TRUE; | |
554 | } | |
555 | ||
556 | bool wxVariantDataChar::Read(istream& WXUNUSED(str)) | |
557 | { | |
558 | wxFAIL_MSG("Unimplemented"); | |
559 | // str >> m_value; | |
560 | return FALSE; | |
561 | } | |
562 | ||
563 | bool wxVariantDataChar::Read(wxString& str) | |
564 | { | |
565 | m_value = str[(size_t)0]; | |
566 | return TRUE; | |
567 | } | |
568 | ||
569 | /* | |
570 | * wxVariantDataString | |
571 | */ | |
572 | ||
573 | class WXDLLEXPORT wxVariantDataString: public wxVariantData | |
574 | { | |
575 | DECLARE_DYNAMIC_CLASS(wxVariantDataString) | |
576 | public: | |
577 | wxVariantDataString() { } | |
578 | wxVariantDataString(const wxString& value) { m_value = value; } | |
579 | ||
580 | inline wxString GetValue() const { return m_value; } | |
581 | inline void SetValue(const wxString& value) { m_value = value; } | |
582 | ||
583 | virtual void Copy(wxVariantData& data); | |
584 | virtual bool Eq(wxVariantData& data) const; | |
585 | virtual bool Write(ostream& str) const; | |
586 | virtual bool Write(wxString& str) const; | |
587 | virtual bool Read(istream& str); | |
588 | virtual bool Read(wxString& str); | |
589 | virtual wxString GetType() const { return "string"; }; | |
590 | ||
591 | protected: | |
592 | wxString m_value; | |
593 | }; | |
594 | ||
595 | void wxVariantDataString::Copy(wxVariantData& data) | |
596 | { | |
597 | wxASSERT_MSG( (data.GetType() == "string"), "wxVariantDataString::Copy: Can't copy to this type of data" ); | |
598 | ||
599 | wxVariantDataString& otherData = (wxVariantDataString&) data; | |
600 | ||
601 | otherData.m_value = m_value; | |
602 | } | |
603 | ||
604 | bool wxVariantDataString::Eq(wxVariantData& data) const | |
605 | { | |
606 | wxASSERT_MSG( (data.GetType() == "string"), "wxVariantDataString::Eq: argument mismatch" ); | |
607 | ||
608 | wxVariantDataString& otherData = (wxVariantDataString&) data; | |
609 | ||
610 | return (otherData.m_value == m_value); | |
611 | } | |
612 | ||
613 | bool wxVariantDataString::Write(ostream& str) const | |
614 | { | |
615 | str << m_value; | |
616 | return TRUE; | |
617 | } | |
618 | ||
619 | bool wxVariantDataString::Write(wxString& str) const | |
620 | { | |
621 | str = m_value; | |
622 | return TRUE; | |
623 | } | |
624 | ||
625 | bool wxVariantDataString::Read(istream& str) | |
626 | { | |
627 | str >> m_value; | |
628 | return TRUE; | |
629 | } | |
630 | ||
631 | bool wxVariantDataString::Read(wxString& str) | |
632 | { | |
633 | m_value = str; | |
634 | return TRUE; | |
635 | } | |
636 | ||
637 | IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData) | |
638 | ||
639 | /* | |
640 | * wxVariant | |
641 | */ | |
642 | ||
643 | IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject) | |
644 | ||
645 | // Construction & destruction | |
646 | wxVariant::wxVariant() | |
647 | { | |
648 | m_data = (wxVariantData*) NULL; | |
649 | } | |
650 | ||
651 | wxVariant::wxVariant(double val) | |
652 | { | |
653 | m_data = new wxVariantDataReal(val); | |
654 | } | |
655 | ||
656 | wxVariant::wxVariant(long val) | |
657 | { | |
658 | m_data = new wxVariantDataLong(val); | |
659 | } | |
660 | ||
661 | wxVariant::wxVariant(bool val) | |
662 | { | |
663 | m_data = new wxVariantDataBool(val); | |
664 | } | |
665 | ||
666 | wxVariant::wxVariant(char val) | |
667 | { | |
668 | m_data = new wxVariantDataChar(val); | |
669 | } | |
670 | ||
671 | wxVariant::wxVariant(const wxString& val) | |
672 | { | |
673 | m_data = new wxVariantDataString(val); | |
674 | } | |
675 | ||
676 | wxVariant::wxVariant(const char* val) | |
677 | { | |
678 | m_data = new wxVariantDataString(wxString(val)); | |
679 | } | |
680 | ||
681 | /* Causes ambiguity | |
682 | wxVariant::wxVariant(const wxStringList& val) | |
683 | { | |
684 | m_data = new wxVariantDataStringList(val); | |
685 | } | |
686 | */ | |
687 | ||
688 | wxVariant::wxVariant(const wxList& val) // List of variants | |
689 | { | |
690 | m_data = new wxVariantDataList(val); | |
691 | } | |
692 | ||
693 | wxVariant::wxVariant(const wxVariant& variant) | |
694 | { | |
695 | if (!variant.IsNull()) | |
696 | { | |
697 | m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject(); | |
698 | variant.m_data->Copy(*m_data); | |
699 | } | |
700 | } | |
701 | ||
702 | wxVariant::wxVariant(wxVariantData* data) // User-defined data | |
703 | { | |
704 | m_data = data; | |
705 | } | |
706 | ||
707 | wxVariant::~wxVariant() | |
708 | { | |
709 | delete m_data; | |
710 | } | |
711 | ||
712 | ||
713 | // Make NULL (i.e. delete the data) | |
714 | void wxVariant::MakeNull() | |
715 | { | |
716 | delete m_data; | |
717 | m_data = NULL; | |
718 | } | |
719 | ||
720 | // Generic operators | |
721 | // Assignment | |
722 | void wxVariant::operator= (const wxVariant& variant) | |
723 | { | |
724 | if (variant.IsNull()) | |
725 | { | |
726 | MakeNull(); | |
727 | return; | |
728 | } | |
729 | ||
730 | if (IsNull() || (GetType() != variant.GetType())) | |
731 | { | |
732 | if (m_data) | |
733 | delete m_data; | |
734 | m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject(); | |
735 | } | |
736 | GetData()->Copy(* variant.GetData()); | |
737 | } | |
738 | ||
739 | // Assignment using data, e.g. | |
740 | // myVariant = new wxStringVariantData("hello") | |
741 | void wxVariant::operator= (wxVariantData* variantData) | |
742 | { | |
743 | MakeNull(); | |
744 | m_data = variantData; | |
745 | } | |
746 | ||
747 | bool wxVariant::operator== (const wxVariant& variant) const | |
748 | { | |
749 | if (IsNull() || variant.IsNull()) | |
750 | return (IsNull() == variant.IsNull()); | |
751 | ||
752 | return (GetData()->Eq(* variant.GetData())); | |
753 | } | |
754 | ||
755 | bool wxVariant::operator!= (const wxVariant& variant) const | |
756 | { | |
757 | return (!(*this == variant)); | |
758 | } | |
759 | ||
760 | ||
761 | // Specific operators | |
762 | bool wxVariant::operator== (double value) const | |
763 | { | |
764 | double thisValue; | |
765 | if (!Convert(&thisValue)) | |
766 | return FALSE; | |
767 | else | |
768 | return (value == thisValue); | |
769 | } | |
770 | ||
771 | bool wxVariant::operator!= (double value) const | |
772 | { | |
773 | return (!((*this) == value)); | |
774 | } | |
775 | ||
776 | void wxVariant::operator= (double value) | |
777 | { | |
778 | if (GetType() == "double") | |
779 | { | |
780 | ((wxVariantDataReal*)GetData())->SetValue(value); | |
781 | } | |
782 | else | |
783 | { | |
784 | if (m_data) | |
785 | delete m_data; | |
786 | m_data = new wxVariantDataReal(value); | |
787 | } | |
788 | } | |
789 | ||
790 | bool wxVariant::operator== (long value) const | |
791 | { | |
792 | long thisValue; | |
793 | if (!Convert(&thisValue)) | |
794 | return FALSE; | |
795 | else | |
796 | return (value == thisValue); | |
797 | } | |
798 | ||
799 | bool wxVariant::operator!= (long value) const | |
800 | { | |
801 | return (!((*this) == value)); | |
802 | } | |
803 | ||
804 | void wxVariant::operator= (long value) | |
805 | { | |
806 | if (GetType() == "long") | |
807 | { | |
808 | ((wxVariantDataLong*)GetData())->SetValue(value); | |
809 | } | |
810 | else | |
811 | { | |
812 | if (m_data) | |
813 | delete m_data; | |
814 | m_data = new wxVariantDataLong(value); | |
815 | } | |
816 | } | |
817 | ||
818 | bool wxVariant::operator== (char value) const | |
819 | { | |
820 | char thisValue; | |
821 | if (!Convert(&thisValue)) | |
822 | return FALSE; | |
823 | else | |
824 | return (value == thisValue); | |
825 | } | |
826 | ||
827 | bool wxVariant::operator!= (char value) const | |
828 | { | |
829 | return (!((*this) == value)); | |
830 | } | |
831 | ||
832 | void wxVariant::operator= (char value) | |
833 | { | |
834 | if (GetType() == "char") | |
835 | { | |
836 | ((wxVariantDataChar*)GetData())->SetValue(value); | |
837 | } | |
838 | else | |
839 | { | |
840 | if (m_data) | |
841 | delete m_data; | |
842 | m_data = new wxVariantDataChar(value); | |
843 | } | |
844 | } | |
845 | ||
846 | bool wxVariant::operator== (bool value) const | |
847 | { | |
848 | bool thisValue; | |
849 | if (!Convert(&thisValue)) | |
850 | return FALSE; | |
851 | else | |
852 | return (value == thisValue); | |
853 | } | |
854 | ||
855 | bool wxVariant::operator!= (bool value) const | |
856 | { | |
857 | return (!((*this) == value)); | |
858 | } | |
859 | ||
860 | void wxVariant::operator= (bool value) | |
861 | { | |
862 | if (GetType() == "bool") | |
863 | { | |
864 | ((wxVariantDataBool*)GetData())->SetValue(value); | |
865 | } | |
866 | else | |
867 | { | |
868 | if (m_data) | |
869 | delete m_data; | |
870 | m_data = new wxVariantDataBool(value); | |
871 | } | |
872 | } | |
873 | ||
874 | bool wxVariant::operator== (const wxString& value) const | |
875 | { | |
876 | wxString thisValue; | |
877 | if (!Convert(&thisValue)) | |
878 | return FALSE; | |
879 | else | |
880 | return (value == thisValue); | |
881 | } | |
882 | ||
883 | bool wxVariant::operator!= (const wxString& value) const | |
884 | { | |
885 | return (!((*this) == value)); | |
886 | } | |
887 | ||
888 | void wxVariant::operator= (const wxString& value) | |
889 | { | |
890 | if (GetType() == "string") | |
891 | { | |
892 | ((wxVariantDataString*)GetData())->SetValue(value); | |
893 | } | |
894 | else | |
895 | { | |
896 | if (m_data) | |
897 | delete m_data; | |
898 | m_data = new wxVariantDataString(value); | |
899 | } | |
900 | } | |
901 | ||
902 | void wxVariant::operator= (const char* value) | |
903 | { | |
904 | if (GetType() == "string") | |
905 | { | |
906 | ((wxVariantDataString*)GetData())->SetValue(wxString(value)); | |
907 | } | |
908 | else | |
909 | { | |
910 | if (m_data) | |
911 | delete m_data; | |
912 | m_data = new wxVariantDataString(wxString(value)); | |
913 | } | |
914 | } | |
915 | ||
916 | bool wxVariant::operator== (const wxStringList& value) const | |
917 | { | |
918 | wxASSERT_MSG( (GetType() == "stringlist"), "Invalid type for == operator" ); | |
919 | ||
920 | wxVariantDataStringList other(value); | |
921 | return (m_data->Eq(other)); | |
922 | } | |
923 | ||
924 | bool wxVariant::operator!= (const wxStringList& value) const | |
925 | { | |
926 | return (!((*this) == value)); | |
927 | } | |
928 | ||
929 | void wxVariant::operator= (const wxStringList& value) | |
930 | { | |
931 | if (GetType() == "stringlist") | |
932 | { | |
933 | ((wxVariantDataStringList*)GetData())->SetValue(value); | |
934 | } | |
935 | else | |
936 | { | |
937 | if (m_data) | |
938 | delete m_data; | |
939 | m_data = new wxVariantDataStringList(value); | |
940 | } | |
941 | } | |
942 | ||
943 | bool wxVariant::operator== (const wxList& value) const | |
944 | { | |
945 | wxASSERT_MSG( (GetType() == "list"), "Invalid type for == operator" ); | |
946 | ||
947 | wxVariantDataList other(value); | |
948 | return (m_data->Eq(other)); | |
949 | } | |
950 | ||
951 | bool wxVariant::operator!= (const wxList& value) const | |
952 | { | |
953 | return (!((*this) == value)); | |
954 | } | |
955 | ||
956 | void wxVariant::operator= (const wxList& value) | |
957 | { | |
958 | if (GetType() == "list") | |
959 | { | |
960 | ((wxVariantDataList*)GetData())->SetValue(value); | |
961 | } | |
962 | else | |
963 | { | |
964 | if (m_data) | |
965 | delete m_data; | |
966 | m_data = new wxVariantDataList(value); | |
967 | } | |
968 | } | |
969 | ||
970 | ||
971 | // Treat a list variant as an array | |
972 | wxVariant wxVariant::operator[] (size_t idx) const | |
973 | { | |
974 | wxASSERT_MSG( (GetType() == "list" || GetType() == "stringlist"), "Invalid type for array operator" ); | |
975 | ||
976 | if (GetType() == "list") | |
977 | { | |
978 | wxVariantDataList* data = (wxVariantDataList*) m_data; | |
979 | wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), "Invalid index for array" ); | |
980 | return * (wxVariant*) (data->GetValue().Nth(idx)->Data()); | |
981 | } | |
982 | else if (GetType() == "stringlist") | |
983 | { | |
984 | wxVariantDataStringList* data = (wxVariantDataStringList*) m_data; | |
985 | wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), "Invalid index for array" ); | |
986 | ||
987 | wxVariant variant( wxString( (char*) (data->GetValue().Nth(idx)->Data()) )); | |
988 | return variant; | |
989 | } | |
990 | return wxNullVariant; | |
991 | } | |
992 | ||
993 | wxVariant& wxVariant::operator[] (size_t idx) | |
994 | { | |
995 | // We can't return a reference to a variant for a string list, since the string | |
996 | // is actually stored as a char*, not a variant. | |
997 | ||
998 | wxASSERT_MSG( (GetType() == "list"), "Invalid type for array operator" ); | |
999 | ||
1000 | wxVariantDataList* data = (wxVariantDataList*) m_data; | |
1001 | wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), "Invalid index for array" ); | |
1002 | ||
1003 | return * (wxVariant*) (data->GetValue().Nth(idx)->Data()); | |
1004 | } | |
1005 | ||
1006 | // Return the number of elements in a list | |
1007 | int wxVariant::GetCount() const | |
1008 | { | |
1009 | wxASSERT_MSG( (GetType() == "list" || GetType() == "stringlist"), "Invalid type for GetCount()" ); | |
1010 | ||
1011 | if (GetType() == "list") | |
1012 | { | |
1013 | wxVariantDataList* data = (wxVariantDataList*) m_data; | |
1014 | return data->GetValue().Number(); | |
1015 | } | |
1016 | else if (GetType() == "stringlist") | |
1017 | { | |
1018 | wxVariantDataStringList* data = (wxVariantDataStringList*) m_data; | |
1019 | return data->GetValue().Number(); | |
1020 | } | |
1021 | return 0; | |
1022 | } | |
1023 | ||
1024 | wxString wxVariant::MakeString() const | |
1025 | { | |
1026 | if (!IsNull()) | |
1027 | { | |
1028 | wxString str; | |
1029 | if (GetData()->Write(str)) | |
1030 | return str; | |
1031 | } | |
1032 | return wxString(""); | |
1033 | } | |
1034 | ||
1035 | // Accessors | |
1036 | ||
1037 | void wxVariant::SetData(wxVariantData* data) | |
1038 | { | |
1039 | if (m_data) delete m_data; | |
1040 | m_data = data; | |
1041 | } | |
1042 | ||
1043 | ||
1044 | // Returns a string representing the type of the variant, | |
1045 | // e.g. "string", "bool", "stringlist", "list", "double", "long" | |
1046 | wxString wxVariant::GetType() const | |
1047 | { | |
1048 | if (IsNull()) | |
1049 | return wxString("null"); | |
1050 | else | |
1051 | return m_data->GetType(); | |
1052 | } | |
1053 | ||
1054 | ||
1055 | bool wxVariant::IsType(const wxString& type) const | |
1056 | { | |
1057 | return (GetType() == type); | |
1058 | } | |
1059 | ||
1060 | ||
1061 | // Value accessors | |
1062 | double wxVariant::GetReal() const | |
1063 | { | |
1064 | double value; | |
1065 | if (Convert(& value)) | |
1066 | return value; | |
1067 | else | |
1068 | { | |
1069 | wxFAIL_MSG("Could not convert to a real number"); | |
1070 | return 0.0; | |
1071 | } | |
1072 | } | |
1073 | ||
1074 | long wxVariant::GetInteger() const | |
1075 | { | |
1076 | long value; | |
1077 | if (Convert(& value)) | |
1078 | return value; | |
1079 | else | |
1080 | { | |
1081 | wxFAIL_MSG("Could not convert to an integer"); | |
1082 | return 0; | |
1083 | } | |
1084 | } | |
1085 | ||
1086 | char wxVariant::GetChar() const | |
1087 | { | |
1088 | char value; | |
1089 | if (Convert(& value)) | |
1090 | return value; | |
1091 | else | |
1092 | { | |
1093 | wxFAIL_MSG("Could not convert to a char"); | |
1094 | return 0; | |
1095 | } | |
1096 | } | |
1097 | ||
1098 | bool wxVariant::GetBool() const | |
1099 | { | |
1100 | bool value; | |
1101 | if (Convert(& value)) | |
1102 | return value; | |
1103 | else | |
1104 | { | |
1105 | wxFAIL_MSG("Could not convert to a bool"); | |
1106 | return 0; | |
1107 | } | |
1108 | } | |
1109 | ||
1110 | wxString wxVariant::GetString() const | |
1111 | { | |
1112 | wxString value; | |
1113 | if (Convert(& value)) | |
1114 | return value; | |
1115 | else | |
1116 | { | |
1117 | wxFAIL_MSG("Could not convert to a string"); | |
1118 | return wxString(""); | |
1119 | } | |
1120 | } | |
1121 | ||
1122 | wxList& wxVariant::GetList() const | |
1123 | { | |
1124 | wxASSERT( (GetType() == "list") ); | |
1125 | ||
1126 | return (wxList&) ((wxVariantDataList*) m_data)->GetValue(); | |
1127 | } | |
1128 | ||
1129 | wxStringList& wxVariant::GetStringList() const | |
1130 | { | |
1131 | wxASSERT( (GetType() == "stringlist") ); | |
1132 | ||
1133 | return (wxStringList&) ((wxVariantDataStringList*) m_data)->GetValue(); | |
1134 | } | |
1135 | ||
1136 | // Append to list | |
1137 | void wxVariant::Append(const wxVariant& value) | |
1138 | { | |
1139 | wxList& list = GetList(); | |
1140 | ||
1141 | list.Append(new wxVariant(value)); | |
1142 | } | |
1143 | ||
1144 | // Insert at front of list | |
1145 | void wxVariant::Insert(const wxVariant& value) | |
1146 | { | |
1147 | wxList& list = GetList(); | |
1148 | ||
1149 | list.Insert(new wxVariant(value)); | |
1150 | } | |
1151 | ||
1152 | // Returns TRUE if the variant is a member of the list | |
1153 | bool wxVariant::Member(const wxVariant& value) const | |
1154 | { | |
1155 | wxList& list = GetList(); | |
1156 | ||
1157 | wxNode* node = list.First(); | |
1158 | while (node) | |
1159 | { | |
1160 | wxVariant* other = (wxVariant*) node->Data(); | |
1161 | if (value == *other) | |
1162 | return TRUE; | |
1163 | node = node->Next(); | |
1164 | } | |
1165 | return FALSE; | |
1166 | } | |
1167 | ||
1168 | // Deletes the nth element of the list | |
1169 | bool wxVariant::Delete(int item) | |
1170 | { | |
1171 | wxList& list = GetList(); | |
1172 | ||
1173 | wxASSERT_MSG( (item < list.Number()), "Invalid index to Delete" ); | |
1174 | wxNode* node = list.Nth(item); | |
1175 | wxVariant* variant = (wxVariant*) node->Data(); | |
1176 | delete variant; | |
1177 | delete node; | |
1178 | return TRUE; | |
1179 | } | |
1180 | ||
1181 | // Clear list | |
1182 | void wxVariant::ClearList() | |
1183 | { | |
1184 | if (!IsNull() && (GetType() == "list")) | |
1185 | { | |
1186 | ((wxVariantDataList*) m_data)->Clear(); | |
1187 | } | |
1188 | else | |
1189 | { | |
1190 | if (GetType() != "list") | |
1191 | { | |
1192 | delete m_data; | |
1193 | m_data = NULL; | |
1194 | } | |
1195 | m_data = new wxVariantDataList; | |
1196 | } | |
1197 | } | |
1198 | ||
1199 | // Type conversion | |
1200 | bool wxVariant::Convert(long* value) const | |
1201 | { | |
1202 | wxString type(GetType()); | |
1203 | if (type == "double") | |
1204 | *value = (long) (((wxVariantDataReal*)GetData())->GetValue()); | |
1205 | else if (type == "long") | |
1206 | *value = ((wxVariantDataLong*)GetData())->GetValue(); | |
1207 | else if (type == "bool") | |
1208 | *value = (long) (((wxVariantDataBool*)GetData())->GetValue()); | |
1209 | else if (type == "string") | |
1210 | *value = atol((const char*) ((wxVariantDataString*)GetData())->GetValue()); | |
1211 | else | |
1212 | return FALSE; | |
1213 | ||
1214 | return TRUE; | |
1215 | } | |
1216 | ||
1217 | bool wxVariant::Convert(bool* value) const | |
1218 | { | |
1219 | wxString type(GetType()); | |
1220 | if (type == "double") | |
1221 | *value = ((int) (((wxVariantDataReal*)GetData())->GetValue()) != 0); | |
1222 | else if (type == "long") | |
1223 | *value = (((wxVariantDataLong*)GetData())->GetValue() != 0); | |
1224 | else if (type == "bool") | |
1225 | *value = ((wxVariantDataBool*)GetData())->GetValue(); | |
1226 | else if (type == "string") | |
1227 | { | |
1228 | wxString val(((wxVariantDataString*)GetData())->GetValue()); | |
1229 | val.MakeLower(); | |
1230 | if (val == "true" || val == "yes") | |
1231 | *value = TRUE; | |
1232 | else if (val == "false" || val == "no") | |
1233 | *value = FALSE; | |
1234 | else | |
1235 | return FALSE; | |
1236 | } | |
1237 | else | |
1238 | return FALSE; | |
1239 | ||
1240 | return TRUE; | |
1241 | } | |
1242 | ||
1243 | bool wxVariant::Convert(double* value) const | |
1244 | { | |
1245 | wxString type(GetType()); | |
1246 | if (type == "double") | |
1247 | *value = ((wxVariantDataReal*)GetData())->GetValue(); | |
1248 | else if (type == "long") | |
1249 | *value = (double) (((wxVariantDataLong*)GetData())->GetValue()); | |
1250 | else if (type == "bool") | |
1251 | *value = (double) (((wxVariantDataBool*)GetData())->GetValue()); | |
1252 | else if (type == "string") | |
1253 | *value = (double) atof((const char*) ((wxVariantDataString*)GetData())->GetValue()); | |
1254 | else | |
1255 | return FALSE; | |
1256 | ||
1257 | return TRUE; | |
1258 | } | |
1259 | ||
1260 | bool wxVariant::Convert(char* value) const | |
1261 | { | |
1262 | wxString type(GetType()); | |
1263 | if (type == "char") | |
1264 | *value = ((wxVariantDataChar*)GetData())->GetValue(); | |
1265 | else if (type == "long") | |
1266 | *value = (char) (((wxVariantDataLong*)GetData())->GetValue()); | |
1267 | else if (type == "bool") | |
1268 | *value = (char) (((wxVariantDataBool*)GetData())->GetValue()); | |
1269 | else | |
1270 | return FALSE; | |
1271 | ||
1272 | return TRUE; | |
1273 | } | |
1274 | ||
1275 | bool wxVariant::Convert(wxString* value) const | |
1276 | { | |
1277 | *value = MakeString(); | |
1278 | return TRUE; | |
1279 | } | |
1280 |