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