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