]> git.saurik.com Git - wxWidgets.git/blob - src/common/variant.cpp
compilation fix for stuff missing from mingw32 headers
[wxWidgets.git] / src / common / variant.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/common/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 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16     #pragma hdrstop
17 #endif
18
19 #include "wx/variant.h"
20
21 #if wxUSE_VARIANT
22
23 #ifndef WX_PRECOMP
24     #include "wx/string.h"
25     #include "wx/math.h"
26     #include "wx/crt.h"
27     #if wxUSE_STREAMS
28         #include "wx/stream.h"
29     #endif
30 #endif
31
32 #if wxUSE_STD_IOSTREAM
33     #if wxUSE_IOSTREAMH
34         #include <fstream.h>
35     #else
36         #include <fstream>
37     #endif
38 #endif
39
40 #if defined(__MWERKS__) && __MSL__ >= 0x6000
41 namespace std {}
42 using namespace std ;
43 #endif
44
45 #if wxUSE_STREAMS
46     #include "wx/txtstrm.h"
47 #endif
48
49 #include "wx/string.h"
50 #include "wx/tokenzr.h"
51
52 wxVariant WXDLLIMPEXP_BASE wxNullVariant;
53
54
55 #include "wx/listimpl.cpp"
56 WX_DEFINE_LIST(wxVariantList)
57
58 /*
59  * wxVariant
60  */
61
62 IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
63
64 wxVariant::wxVariant()
65 {
66     m_data = (wxVariantData*) NULL;
67 }
68
69 bool wxVariant::IsNull() const
70 {
71      return (m_data == (wxVariantData*) NULL);
72 }
73
74 void wxVariant::MakeNull()
75 {
76     UnRef();
77 }
78
79 void wxVariant::Clear()
80 {
81     m_name = wxEmptyString;
82 }
83
84 wxVariant::wxVariant(const wxVariant& variant)
85     : wxObject()
86 {
87     m_data = (wxVariantData*) NULL;
88
89     if (!variant.IsNull())
90         Ref(variant);
91
92     m_name = variant.m_name;
93 }
94
95 wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
96 {
97     m_data = data;
98     m_name = name;
99 }
100
101 wxVariant::~wxVariant()
102 {
103     UnRef();
104 }
105
106 // Assignment
107 void wxVariant::operator= (const wxVariant& variant)
108 {
109     Ref(variant);
110     m_name = variant.m_name;
111 }
112
113 // myVariant = new wxStringVariantData("hello")
114 void wxVariant::operator= (wxVariantData* variantData)
115 {
116     UnRef();
117     m_data = variantData;
118 }
119
120 bool wxVariant::operator== (const wxVariant& variant) const
121 {
122     if (IsNull() || variant.IsNull())
123         return (IsNull() == variant.IsNull());
124
125     return (GetData()->Eq(* variant.GetData()));
126 }
127
128 bool wxVariant::operator!= (const wxVariant& variant) const
129 {
130     return (!(*this == variant));
131 }
132
133 wxString wxVariant::MakeString() const
134 {
135     if (!IsNull())
136     {
137         wxString str;
138         if (GetData()->Write(str))
139             return str;
140     }
141     return wxEmptyString;
142 }
143
144 void wxVariant::SetData(wxVariantData* data)
145 {
146     UnRef();
147     m_data = data;
148 }
149
150 void wxVariant::Ref(const wxVariant& clone)
151 {
152     // nothing to be done
153     if (m_data == clone.m_data)
154         return;
155
156     // delete reference to old data
157     UnRef();
158
159     // reference new data
160     if ( clone.m_data )
161     {
162         m_data = clone.m_data;
163         m_data->m_count++;
164     }
165 }
166
167
168 void wxVariant::UnRef()
169 {
170     if ( m_data )
171     {
172         wxASSERT_MSG( m_data->m_count > 0, _T("invalid ref data count") );
173
174         m_data->DecRef();
175         m_data = NULL;
176     }
177 }
178
179 bool wxVariant::Unshare()
180 {
181     if ( m_data && m_data->GetRefCount() > 1 )
182     {
183         // note that ref is not going to be destroyed in this case...
184         const wxVariantData* ref = m_data;
185         UnRef();
186
187         // ... so we can still access it
188         m_data = ref->Clone();
189
190         wxASSERT_MSG( (m_data && m_data->GetRefCount() == 1),
191                   _T("wxVariant::AllocExclusive() failed.") );
192
193         if (!m_data || m_data->GetRefCount() != 1)
194             return false;
195         else
196             return true;
197     }
198     //else: data is null or ref count is 1, so we are exclusive owners of m_refData anyhow
199     else
200         return true;
201 }
202
203
204 // Returns a string representing the type of the variant,
205 // e.g. "string", "bool", "list", "double", "long"
206 wxString wxVariant::GetType() const
207 {
208     if (IsNull())
209         return wxString(wxT("null"));
210     else
211         return GetData()->GetType();
212 }
213
214
215 bool wxVariant::IsType(const wxString& type) const
216 {
217     return (GetType() == type);
218 }
219
220 bool wxVariant::IsValueKindOf(const wxClassInfo* type) const
221 {
222     wxClassInfo* info=GetData()->GetValueClassInfo();
223     return info ? info->IsKindOf(type) : false ;
224 }
225
226
227 // -----------------------------------------------------------------
228 // wxVariantDataLong
229 // -----------------------------------------------------------------
230
231 class WXDLLIMPEXP_BASE wxVariantDataLong: public wxVariantData
232 {
233 public:
234     wxVariantDataLong() { m_value = 0; }
235     wxVariantDataLong(long value) { m_value = value; }
236
237     inline long GetValue() const { return m_value; }
238     inline void SetValue(long value) { m_value = value; }
239
240     virtual bool Eq(wxVariantData& data) const;
241
242     virtual bool Read(wxString& str);
243     virtual bool Write(wxString& str) const;
244 #if wxUSE_STD_IOSTREAM
245     virtual bool Read(wxSTD istream& str);
246     virtual bool Write(wxSTD ostream& str) const;
247 #endif
248 #if wxUSE_STREAMS
249     virtual bool Read(wxInputStream& str);
250     virtual bool Write(wxOutputStream &str) const;
251 #endif // wxUSE_STREAMS
252
253     wxVariantData* Clone() const { return new wxVariantDataLong(m_value); }
254
255     virtual wxString GetType() const { return wxT("long"); }
256
257 protected:
258     long m_value;
259 };
260
261 bool wxVariantDataLong::Eq(wxVariantData& data) const
262 {
263     wxASSERT_MSG( (data.GetType() == wxT("long")), wxT("wxVariantDataLong::Eq: argument mismatch") );
264
265     wxVariantDataLong& otherData = (wxVariantDataLong&) data;
266
267     return (otherData.m_value == m_value);
268 }
269
270 #if wxUSE_STD_IOSTREAM
271 bool wxVariantDataLong::Write(wxSTD ostream& str) const
272 {
273     wxString s;
274     Write(s);
275     str << (const char*) s.mb_str();
276     return true;
277 }
278 #endif
279
280 bool wxVariantDataLong::Write(wxString& str) const
281 {
282     str.Printf(wxT("%ld"), m_value);
283     return true;
284 }
285
286 #if wxUSE_STD_IOSTREAM
287 bool wxVariantDataLong::Read(wxSTD istream& str)
288 {
289     str >> m_value;
290     return true;
291 }
292 #endif
293
294 #if wxUSE_STREAMS
295 bool wxVariantDataLong::Write(wxOutputStream& str) const
296 {
297     wxTextOutputStream s(str);
298
299     s.Write32((size_t)m_value);
300     return true;
301 }
302
303 bool wxVariantDataLong::Read(wxInputStream& str)
304 {
305    wxTextInputStream s(str);
306    m_value = s.Read32();
307    return true;
308 }
309 #endif // wxUSE_STREAMS
310
311 bool wxVariantDataLong::Read(wxString& str)
312 {
313     m_value = wxAtol(str);
314     return true;
315 }
316
317 // wxVariant
318
319 wxVariant::wxVariant(long val, const wxString& name)
320 {
321     m_data = new wxVariantDataLong(val);
322     m_name = name;
323 }
324
325 wxVariant::wxVariant(int val, const wxString& name)
326 {
327     m_data = new wxVariantDataLong((long)val);
328     m_name = name;
329 }
330
331 wxVariant::wxVariant(short val, const wxString& name)
332 {
333     m_data = new wxVariantDataLong((long)val);
334     m_name = name;
335 }
336
337 bool wxVariant::operator== (long value) const
338 {
339     long thisValue;
340     if (!Convert(&thisValue))
341         return false;
342     else
343         return (value == thisValue);
344 }
345
346 bool wxVariant::operator!= (long value) const
347 {
348     return (!((*this) == value));
349 }
350
351 void wxVariant::operator= (long value)
352 {
353     if (GetType() == wxT("long") &&
354         m_data->GetRefCount() == 1)
355     {
356         ((wxVariantDataLong*)GetData())->SetValue(value);
357     }
358     else
359     {
360         UnRef();
361         m_data = new wxVariantDataLong(value);
362     }
363 }
364
365 long wxVariant::GetLong() const
366 {
367     long value;
368     if (Convert(& value))
369         return value;
370     else
371     {
372         wxFAIL_MSG(wxT("Could not convert to a long"));
373         return 0;
374     }
375 }
376
377 // -----------------------------------------------------------------
378 // wxVariantDoubleData
379 // -----------------------------------------------------------------
380
381 class WXDLLIMPEXP_BASE wxVariantDoubleData: public wxVariantData
382 {
383 public:
384     wxVariantDoubleData() { m_value = 0.0; }
385     wxVariantDoubleData(double value) { m_value = value; }
386
387     inline double GetValue() const { return m_value; }
388     inline void SetValue(double value) { m_value = value; }
389
390     virtual bool Eq(wxVariantData& data) const;
391     virtual bool Read(wxString& str);
392 #if wxUSE_STD_IOSTREAM
393     virtual bool Write(wxSTD ostream& str) const;
394 #endif
395     virtual bool Write(wxString& str) const;
396 #if wxUSE_STD_IOSTREAM
397     virtual bool Read(wxSTD istream& str);
398 #endif
399 #if wxUSE_STREAMS
400     virtual bool Read(wxInputStream& str);
401     virtual bool Write(wxOutputStream &str) const;
402 #endif // wxUSE_STREAMS
403     virtual wxString GetType() const { return wxT("double"); }
404
405     wxVariantData* Clone() const { return new wxVariantDoubleData(m_value); }
406 protected:
407     double m_value;
408 };
409
410 bool wxVariantDoubleData::Eq(wxVariantData& data) const
411 {
412     wxASSERT_MSG( (data.GetType() == wxT("double")), wxT("wxVariantDoubleData::Eq: argument mismatch") );
413
414     wxVariantDoubleData& otherData = (wxVariantDoubleData&) data;
415
416     return wxIsSameDouble(otherData.m_value, m_value);
417 }
418
419 #if wxUSE_STD_IOSTREAM
420 bool wxVariantDoubleData::Write(wxSTD ostream& str) const
421 {
422     wxString s;
423     Write(s);
424     str << (const char*) s.mb_str();
425     return true;
426 }
427 #endif
428
429 bool wxVariantDoubleData::Write(wxString& str) const
430 {
431     str.Printf(wxT("%.14g"), m_value);
432     return true;
433 }
434
435 #if wxUSE_STD_IOSTREAM
436 bool wxVariantDoubleData::Read(wxSTD istream& str)
437 {
438     str >> m_value;
439     return true;
440 }
441 #endif
442
443 #if wxUSE_STREAMS
444 bool wxVariantDoubleData::Write(wxOutputStream& str) const
445 {
446     wxTextOutputStream s(str);
447     s.WriteDouble((double)m_value);
448     return true;
449 }
450
451 bool wxVariantDoubleData::Read(wxInputStream& str)
452 {
453     wxTextInputStream s(str);
454     m_value = (float)s.ReadDouble();
455     return true;
456 }
457 #endif // wxUSE_STREAMS
458
459 bool wxVariantDoubleData::Read(wxString& str)
460 {
461     m_value = wxAtof(str);
462     return true;
463 }
464
465 //  wxVariant double code
466
467 wxVariant::wxVariant(double val, const wxString& name)
468 {
469     m_data = new wxVariantDoubleData(val);
470     m_name = name;
471 }
472
473 bool wxVariant::operator== (double value) const
474 {
475     double thisValue;
476     if (!Convert(&thisValue))
477         return false;
478
479     return wxIsSameDouble(value, thisValue);
480 }
481
482 bool wxVariant::operator!= (double value) const
483 {
484     return (!((*this) == value));
485 }
486
487 void wxVariant::operator= (double value)
488 {
489     if (GetType() == wxT("double") &&
490         m_data->GetRefCount() == 1)
491     {
492         ((wxVariantDoubleData*)GetData())->SetValue(value);
493     }
494     else
495     {
496         UnRef();
497         m_data = new wxVariantDoubleData(value);
498     }
499 }
500
501 double wxVariant::GetDouble() const
502 {
503     double value;
504     if (Convert(& value))
505         return value;
506     else
507     {
508         wxFAIL_MSG(wxT("Could not convert to a double number"));
509         return 0.0;
510     }
511 }
512
513 // -----------------------------------------------------------------
514 // wxVariantBoolData
515 // -----------------------------------------------------------------
516
517 #ifdef HAVE_BOOL
518
519 class WXDLLIMPEXP_BASE wxVariantDataBool: public wxVariantData
520 {
521 public:
522     wxVariantDataBool() { m_value = 0; }
523     wxVariantDataBool(bool value) { m_value = value; }
524
525     inline bool GetValue() const { return m_value; }
526     inline void SetValue(bool value) { m_value = value; }
527
528     virtual bool Eq(wxVariantData& data) const;
529 #if wxUSE_STD_IOSTREAM
530     virtual bool Write(wxSTD ostream& str) const;
531 #endif
532     virtual bool Write(wxString& str) const;
533     virtual bool Read(wxString& str);
534 #if wxUSE_STD_IOSTREAM
535     virtual bool Read(wxSTD istream& str);
536 #endif
537 #if wxUSE_STREAMS
538     virtual bool Read(wxInputStream& str);
539     virtual bool Write(wxOutputStream& str) const;
540 #endif // wxUSE_STREAMS
541     virtual wxString GetType() const { return wxT("bool"); }
542
543     wxVariantData* Clone() const { return new wxVariantDataBool(m_value); }
544 protected:
545     bool m_value;
546 };
547
548 bool wxVariantDataBool::Eq(wxVariantData& data) const
549 {
550     wxASSERT_MSG( (data.GetType() == wxT("bool")), wxT("wxVariantDataBool::Eq: argument mismatch") );
551
552     wxVariantDataBool& otherData = (wxVariantDataBool&) data;
553
554     return (otherData.m_value == m_value);
555 }
556
557 #if wxUSE_STD_IOSTREAM
558 bool wxVariantDataBool::Write(wxSTD ostream& str) const
559 {
560     wxString s;
561     Write(s);
562     str << (const char*) s.mb_str();
563     return true;
564 }
565 #endif
566
567 bool wxVariantDataBool::Write(wxString& str) const
568 {
569     str.Printf(wxT("%d"), (int) m_value);
570     return true;
571 }
572
573 #if wxUSE_STD_IOSTREAM
574 bool wxVariantDataBool::Read(wxSTD istream& WXUNUSED(str))
575 {
576     wxFAIL_MSG(wxT("Unimplemented"));
577 //    str >> (long) m_value;
578     return false;
579 }
580 #endif
581
582 #if wxUSE_STREAMS
583 bool wxVariantDataBool::Write(wxOutputStream& str) const
584 {
585     wxTextOutputStream s(str);
586
587     s.Write8(m_value);
588     return true;
589 }
590
591 bool wxVariantDataBool::Read(wxInputStream& str)
592 {
593     wxTextInputStream s(str);
594
595     m_value = s.Read8() != 0;
596     return true;
597 }
598 #endif // wxUSE_STREAMS
599
600 bool wxVariantDataBool::Read(wxString& str)
601 {
602     m_value = (wxAtol(str) != 0);
603     return true;
604 }
605
606 // wxVariant ****
607
608 wxVariant::wxVariant(bool val, const wxString& name)
609 {
610     m_data = new wxVariantDataBool(val);
611     m_name = name;
612 }
613
614 bool wxVariant::operator== (bool value) const
615 {
616     bool thisValue;
617     if (!Convert(&thisValue))
618         return false;
619     else
620         return (value == thisValue);
621 }
622
623 bool wxVariant::operator!= (bool value) const
624 {
625     return (!((*this) == value));
626 }
627
628 void wxVariant::operator= (bool value)
629 {
630     if (GetType() == wxT("bool") &&
631         m_data->GetRefCount() == 1)
632     {
633         ((wxVariantDataBool*)GetData())->SetValue(value);
634     }
635     else
636     {
637         UnRef();
638         m_data = new wxVariantDataBool(value);
639     }
640 }
641
642 bool wxVariant::GetBool() const
643 {
644     bool value;
645     if (Convert(& value))
646         return value;
647     else
648     {
649         wxFAIL_MSG(wxT("Could not convert to a bool"));
650         return 0;
651     }
652 }
653
654 #endif // HAVE_BOOL
655
656 // -----------------------------------------------------------------
657 // wxVariantDataChar
658 // -----------------------------------------------------------------
659
660 class WXDLLIMPEXP_BASE wxVariantDataChar: public wxVariantData
661 {
662 public:
663     wxVariantDataChar() { m_value = 0; }
664     wxVariantDataChar(const wxUniChar& value) { m_value = value; }
665
666     inline wxUniChar GetValue() const { return m_value; }
667     inline void SetValue(const wxUniChar& value) { m_value = value; }
668
669     virtual bool Eq(wxVariantData& data) const;
670 #if wxUSE_STD_IOSTREAM
671     virtual bool Read(wxSTD istream& str);
672     virtual bool Write(wxSTD ostream& str) const;
673 #endif
674     virtual bool Read(wxString& str);
675     virtual bool Write(wxString& str) const;
676 #if wxUSE_STREAMS
677     virtual bool Read(wxInputStream& str);
678     virtual bool Write(wxOutputStream& str) const;
679 #endif // wxUSE_STREAMS
680     virtual wxString GetType() const { return wxT("char"); }
681     wxVariantData* Clone() const { return new wxVariantDataChar(m_value); }
682
683 protected:
684     wxUniChar m_value;
685 };
686
687 bool wxVariantDataChar::Eq(wxVariantData& data) const
688 {
689     wxASSERT_MSG( (data.GetType() == wxT("char")), wxT("wxVariantDataChar::Eq: argument mismatch") );
690
691     wxVariantDataChar& otherData = (wxVariantDataChar&) data;
692
693     return (otherData.m_value == m_value);
694 }
695
696 #if wxUSE_STD_IOSTREAM
697 bool wxVariantDataChar::Write(wxSTD ostream& str) const
698 {
699     str << wxString(m_value);
700     return true;
701 }
702 #endif
703
704 bool wxVariantDataChar::Write(wxString& str) const
705 {
706     str = m_value;
707     return true;
708 }
709
710 #if wxUSE_STD_IOSTREAM
711 bool wxVariantDataChar::Read(wxSTD istream& WXUNUSED(str))
712 {
713     wxFAIL_MSG(wxT("Unimplemented"));
714
715     return false;
716 }
717 #endif
718
719 #if wxUSE_STREAMS
720 bool wxVariantDataChar::Write(wxOutputStream& str) const
721 {
722     wxTextOutputStream s(str);
723
724     // FIXME-UTF8: this should be just "s << m_value;" after removal of
725     //             ANSI build and addition of wxUniChar to wxTextOutputStream:
726     s << (wxChar)m_value;
727
728     return true;
729 }
730
731 bool wxVariantDataChar::Read(wxInputStream& str)
732 {
733     wxTextInputStream s(str);
734
735     // FIXME-UTF8: this should be just "s >> m_value;" after removal of
736     //             ANSI build and addition of wxUniChar to wxTextInputStream:
737     wxChar ch;
738     s >> ch;
739     m_value = ch;
740
741     return true;
742 }
743 #endif // wxUSE_STREAMS
744
745 bool wxVariantDataChar::Read(wxString& str)
746 {
747     m_value = str[0u];
748     return true;
749 }
750
751 wxVariant::wxVariant(const wxUniChar& val, const wxString& name)
752 {
753     m_data = new wxVariantDataChar(val);
754     m_name = name;
755 }
756
757 wxVariant::wxVariant(char val, const wxString& name)
758 {
759     m_data = new wxVariantDataChar(val);
760     m_name = name;
761 }
762
763 wxVariant::wxVariant(wchar_t val, const wxString& name)
764 {
765     m_data = new wxVariantDataChar(val);
766     m_name = name;
767 }
768
769 bool wxVariant::operator==(const wxUniChar& value) const
770 {
771     wxUniChar thisValue;
772     if (!Convert(&thisValue))
773         return false;
774     else
775         return (value == thisValue);
776 }
777
778 wxVariant& wxVariant::operator=(const wxUniChar& value)
779 {
780     if (GetType() == wxT("char") &&
781         m_data->GetRefCount() == 1)
782     {
783         ((wxVariantDataChar*)GetData())->SetValue(value);
784     }
785     else
786     {
787         UnRef();
788         m_data = new wxVariantDataChar(value);
789     }
790
791     return *this;
792 }
793
794 wxUniChar wxVariant::GetChar() const
795 {
796     wxUniChar value;
797     if (Convert(& value))
798         return value;
799     else
800     {
801         wxFAIL_MSG(wxT("Could not convert to a char"));
802         return wxUniChar(0);
803     }
804 }
805
806 // ----------------------------------------------------------------------------
807 // wxVariantDataString
808 // ----------------------------------------------------------------------------
809
810 class WXDLLIMPEXP_BASE wxVariantDataString: public wxVariantData
811 {
812 public:
813     wxVariantDataString() { }
814     wxVariantDataString(const wxString& value) { m_value = value; }
815
816     inline wxString GetValue() const { return m_value; }
817     inline void SetValue(const wxString& value) { m_value = value; }
818
819     virtual bool Eq(wxVariantData& data) const;
820 #if wxUSE_STD_IOSTREAM
821     virtual bool Write(wxSTD ostream& str) const;
822 #endif
823     virtual bool Read(wxString& str);
824     virtual bool Write(wxString& str) const;
825 #if wxUSE_STD_IOSTREAM
826     virtual bool Read(wxSTD istream& WXUNUSED(str)) { return false; }
827 #endif
828 #if wxUSE_STREAMS
829     virtual bool Read(wxInputStream& str);
830     virtual bool Write(wxOutputStream& str) const;
831 #endif // wxUSE_STREAMS
832     virtual wxString GetType() const { return wxT("string"); }
833     wxVariantData* Clone() const { return new wxVariantDataString(m_value); }
834
835 protected:
836     wxString m_value;
837 };
838
839 bool wxVariantDataString::Eq(wxVariantData& data) const
840 {
841     wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
842
843     wxVariantDataString& otherData = (wxVariantDataString&) data;
844
845     return (otherData.m_value == m_value);
846 }
847
848 #if wxUSE_STD_IOSTREAM
849 bool wxVariantDataString::Write(wxSTD ostream& str) const
850 {
851     str << (const char*) m_value.mb_str();
852     return true;
853 }
854 #endif
855
856 bool wxVariantDataString::Write(wxString& str) const
857 {
858     str = m_value;
859     return true;
860 }
861
862 #if wxUSE_STREAMS
863 bool wxVariantDataString::Write(wxOutputStream& str) const
864 {
865   // why doesn't wxOutputStream::operator<< take "const wxString&"
866     wxTextOutputStream s(str);
867     s.WriteString(m_value);
868     return true;
869 }
870
871 bool wxVariantDataString::Read(wxInputStream& str)
872 {
873     wxTextInputStream s(str);
874
875     m_value = s.ReadLine();
876     return true;
877 }
878 #endif // wxUSE_STREAMS
879
880 bool wxVariantDataString::Read(wxString& str)
881 {
882     m_value = str;
883     return true;
884 }
885
886 // wxVariant ****
887
888 wxVariant::wxVariant(const wxString& val, const wxString& name)
889 {
890     m_data = new wxVariantDataString(val);
891     m_name = name;
892 }
893
894 wxVariant::wxVariant(const char* val, const wxString& name)
895 {
896     m_data = new wxVariantDataString(wxString(val));
897     m_name = name;
898 }
899
900 wxVariant::wxVariant(const wchar_t* val, const wxString& name)
901 {
902     m_data = new wxVariantDataString(wxString(val));
903     m_name = name;
904 }
905
906 wxVariant::wxVariant(const wxCStrData& val, const wxString& name)
907 {
908     m_data = new wxVariantDataString(val.AsString());
909     m_name = name;
910 }
911
912 wxVariant::wxVariant(const wxCharBuffer& val, const wxString& name)
913 {
914     m_data = new wxVariantDataString(wxString(val));
915     m_name = name;
916 }
917
918 wxVariant::wxVariant(const wxWCharBuffer& val, const wxString& name)
919 {
920     m_data = new wxVariantDataString(wxString(val));
921     m_name = name;
922 }
923
924 bool wxVariant::operator== (const wxString& value) const
925 {
926     wxString thisValue;
927     if (!Convert(&thisValue))
928         return false;
929
930     return value == thisValue;
931 }
932
933 bool wxVariant::operator!= (const wxString& value) const
934 {
935     return (!((*this) == value));
936 }
937
938 wxVariant& wxVariant::operator= (const wxString& value)
939 {
940     if (GetType() == wxT("string") &&
941         m_data->GetRefCount() == 1)
942     {
943         ((wxVariantDataString*)GetData())->SetValue(value);
944     }
945     else
946     {
947         UnRef();
948         m_data = new wxVariantDataString(value);
949     }
950     return *this;
951 }
952
953 wxString wxVariant::GetString() const
954 {
955     wxString value;
956     if (!Convert(& value))
957     {
958         wxFAIL_MSG(wxT("Could not convert to a string"));
959     }
960
961     return value;
962 }
963
964 // ----------------------------------------------------------------------------
965 // wxVariantDataWxObjectPtr
966 // ----------------------------------------------------------------------------
967
968 class wxVariantDataWxObjectPtr: public wxVariantData
969 {
970 public:
971     wxVariantDataWxObjectPtr() { }
972     wxVariantDataWxObjectPtr(wxObject* value) { m_value = value; }
973
974     inline wxObject* GetValue() const { return m_value; }
975     inline void SetValue(wxObject* value) { m_value = value; }
976
977     virtual bool Eq(wxVariantData& data) const;
978 #if wxUSE_STD_IOSTREAM
979     virtual bool Write(wxSTD ostream& str) const;
980 #endif
981     virtual bool Write(wxString& str) const;
982 #if wxUSE_STD_IOSTREAM
983     virtual bool Read(wxSTD istream& str);
984 #endif
985     virtual bool Read(wxString& str);
986     virtual wxString GetType() const ;
987     virtual wxVariantData* Clone() const { return new wxVariantDataWxObjectPtr(m_value); }
988
989     virtual wxClassInfo* GetValueClassInfo();
990
991 protected:
992     wxObject* m_value;
993 };
994
995 bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const
996 {
997     wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
998
999     wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
1000
1001     return (otherData.m_value == m_value);
1002 }
1003
1004 wxString wxVariantDataWxObjectPtr::GetType() const
1005 {
1006     wxString returnVal(wxT("wxObject*"));
1007
1008     if (m_value)
1009     {
1010         returnVal = m_value->GetClassInfo()->GetClassName();
1011         returnVal += wxT("*");
1012     }
1013
1014     return returnVal;
1015 }
1016
1017 wxClassInfo* wxVariantDataWxObjectPtr::GetValueClassInfo()
1018 {
1019     wxClassInfo* returnVal=NULL;
1020
1021     if (m_value) returnVal = m_value->GetClassInfo();
1022
1023     return returnVal;
1024 }
1025
1026 #if wxUSE_STD_IOSTREAM
1027 bool wxVariantDataWxObjectPtr::Write(wxSTD ostream& str) const
1028 {
1029     wxString s;
1030     Write(s);
1031     str << (const char*) s.mb_str();
1032     return true;
1033 }
1034 #endif
1035
1036 bool wxVariantDataWxObjectPtr::Write(wxString& str) const
1037 {
1038     str.Printf(wxT("%s(%p)"), GetType().c_str(), wx_static_cast(void*, m_value));
1039     return true;
1040 }
1041
1042 #if wxUSE_STD_IOSTREAM
1043 bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
1044 {
1045     // Not implemented
1046     return false;
1047 }
1048 #endif
1049
1050 bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
1051 {
1052     // Not implemented
1053     return false;
1054 }
1055
1056 // wxVariant
1057
1058 wxVariant::wxVariant( wxObject* val, const wxString& name)
1059 {
1060     m_data = new wxVariantDataWxObjectPtr(val);
1061     m_name = name;
1062 }
1063
1064 bool wxVariant::operator== (wxObject* value) const
1065 {
1066     return (value == ((wxVariantDataWxObjectPtr*)GetData())->GetValue());
1067 }
1068
1069 bool wxVariant::operator!= (wxObject* value) const
1070 {
1071     return (!((*this) == (wxObject*) value));
1072 }
1073
1074 void wxVariant::operator= (wxObject* value)
1075 {
1076     UnRef();
1077     m_data = new wxVariantDataWxObjectPtr(value);
1078 }
1079
1080 wxObject* wxVariant::GetWxObjectPtr() const
1081 {
1082     return (wxObject*) ((wxVariantDataWxObjectPtr*) m_data)->GetValue();
1083 }
1084
1085 // ----------------------------------------------------------------------------
1086 // wxVariantDataVoidPtr
1087 // ----------------------------------------------------------------------------
1088
1089 class wxVariantDataVoidPtr: public wxVariantData
1090 {
1091 public:
1092     wxVariantDataVoidPtr() { }
1093     wxVariantDataVoidPtr(void* value) { m_value = value; }
1094
1095     inline void* GetValue() const { return m_value; }
1096     inline void SetValue(void* value) { m_value = value; }
1097
1098     virtual bool Eq(wxVariantData& data) const;
1099 #if wxUSE_STD_IOSTREAM
1100     virtual bool Write(wxSTD ostream& str) const;
1101 #endif
1102     virtual bool Write(wxString& str) const;
1103 #if wxUSE_STD_IOSTREAM
1104     virtual bool Read(wxSTD istream& str);
1105 #endif
1106     virtual bool Read(wxString& str);
1107     virtual wxString GetType() const { return wxT("void*"); }
1108     virtual wxVariantData* Clone() const { return new wxVariantDataVoidPtr(m_value); }
1109
1110 protected:
1111     void* m_value;
1112 };
1113
1114 bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
1115 {
1116     wxASSERT_MSG( data.GetType() == wxT("void*"), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
1117
1118     wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
1119
1120     return (otherData.m_value == m_value);
1121 }
1122
1123 #if wxUSE_STD_IOSTREAM
1124 bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
1125 {
1126     wxString s;
1127     Write(s);
1128     str << (const char*) s.mb_str();
1129     return true;
1130 }
1131 #endif
1132
1133 bool wxVariantDataVoidPtr::Write(wxString& str) const
1134 {
1135     str.Printf(wxT("%p"), m_value);
1136     return true;
1137 }
1138
1139 #if wxUSE_STD_IOSTREAM
1140 bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
1141 {
1142     // Not implemented
1143     return false;
1144 }
1145 #endif
1146
1147 bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
1148 {
1149     // Not implemented
1150     return false;
1151 }
1152
1153 // wxVariant
1154
1155 wxVariant::wxVariant( void* val, const wxString& name)
1156 {
1157     m_data = new wxVariantDataVoidPtr(val);
1158     m_name = name;
1159 }
1160
1161 bool wxVariant::operator== (void* value) const
1162 {
1163     return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
1164 }
1165
1166 bool wxVariant::operator!= (void* value) const
1167 {
1168     return (!((*this) == (void*) value));
1169 }
1170
1171 void wxVariant::operator= (void* value)
1172 {
1173     if (GetType() == wxT("void*") && (m_data->GetRefCount() == 1))
1174     {
1175         ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1176     }
1177     else
1178     {
1179         UnRef();
1180         m_data = new wxVariantDataVoidPtr(value);
1181     }
1182 }
1183
1184 void* wxVariant::GetVoidPtr() const
1185 {
1186     wxASSERT( (GetType() == wxT("void*")) );
1187
1188     return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
1189 }
1190
1191 // ----------------------------------------------------------------------------
1192 // wxVariantDataDateTime
1193 // ----------------------------------------------------------------------------
1194
1195 #if wxUSE_DATETIME
1196
1197 class wxVariantDataDateTime: public wxVariantData
1198 {
1199 public:
1200     wxVariantDataDateTime() { }
1201     wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
1202
1203     inline wxDateTime GetValue() const { return m_value; }
1204     inline void SetValue(const wxDateTime& value) { m_value = value; }
1205
1206     virtual bool Eq(wxVariantData& data) const;
1207 #if wxUSE_STD_IOSTREAM
1208     virtual bool Write(wxSTD ostream& str) const;
1209 #endif
1210     virtual bool Write(wxString& str) const;
1211 #if wxUSE_STD_IOSTREAM
1212     virtual bool Read(wxSTD istream& str);
1213 #endif
1214     virtual bool Read(wxString& str);
1215     virtual wxString GetType() const { return wxT("datetime"); }
1216     virtual wxVariantData* Clone() const { return new wxVariantDataDateTime(m_value); }
1217
1218 protected:
1219     wxDateTime m_value;
1220 };
1221
1222
1223 bool wxVariantDataDateTime::Eq(wxVariantData& data) const
1224 {
1225     wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
1226
1227     wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1228
1229     return (otherData.m_value == m_value);
1230 }
1231
1232
1233 #if wxUSE_STD_IOSTREAM
1234 bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
1235 {
1236     wxString value;
1237     Write( value );
1238     str << value.c_str();
1239     return true;
1240 }
1241 #endif
1242
1243
1244 bool wxVariantDataDateTime::Write(wxString& str) const
1245 {
1246     str = m_value.Format();
1247     return true;
1248 }
1249
1250
1251 #if wxUSE_STD_IOSTREAM
1252 bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
1253 {
1254     // Not implemented
1255     return false;
1256 }
1257 #endif
1258
1259
1260 bool wxVariantDataDateTime::Read(wxString& str)
1261 {
1262     if(! m_value.ParseDateTime(str.c_str()/*FIXME-UTF8*/))
1263         return false;
1264     return true;
1265 }
1266
1267 // wxVariant
1268
1269 wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1270 {
1271     m_data = new wxVariantDataDateTime(val);
1272     m_name = name;
1273 }
1274
1275 bool wxVariant::operator== (const wxDateTime& value) const
1276 {
1277     wxDateTime thisValue;
1278     if (!Convert(&thisValue))
1279         return false;
1280
1281     return value.IsEqualTo(thisValue);
1282 }
1283
1284 bool wxVariant::operator!= (const wxDateTime& value) const
1285 {
1286     return (!((*this) == value));
1287 }
1288
1289 void wxVariant::operator= (const wxDateTime& value)
1290 {
1291     if (GetType() == wxT("datetime") &&
1292         m_data->GetRefCount() == 1)
1293     {
1294         ((wxVariantDataDateTime*)GetData())->SetValue(value);
1295     }
1296     else
1297     {
1298         UnRef();
1299         m_data = new wxVariantDataDateTime(value);
1300     }
1301 }
1302
1303 wxDateTime wxVariant::GetDateTime() const
1304 {
1305     wxDateTime value;
1306     if (!Convert(& value))
1307     {
1308         wxFAIL_MSG(wxT("Could not convert to a datetime"));
1309     }
1310
1311     return value;
1312 }
1313
1314 #endif // wxUSE_DATETIME
1315
1316 // ----------------------------------------------------------------------------
1317 // wxVariantDataArrayString
1318 // ----------------------------------------------------------------------------
1319
1320 class wxVariantDataArrayString: public wxVariantData
1321 {
1322 public:
1323     wxVariantDataArrayString() { }
1324     wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
1325
1326     wxArrayString GetValue() const { return m_value; }
1327     void SetValue(const wxArrayString& value) { m_value = value; }
1328
1329     virtual bool Eq(wxVariantData& data) const;
1330 #if wxUSE_STD_IOSTREAM
1331     virtual bool Write(wxSTD ostream& str) const;
1332 #endif
1333     virtual bool Write(wxString& str) const;
1334 #if wxUSE_STD_IOSTREAM
1335     virtual bool Read(wxSTD istream& str);
1336 #endif
1337     virtual bool Read(wxString& str);
1338     virtual wxString GetType() const { return wxT("arrstring"); }
1339     virtual wxVariantData* Clone() const { return new wxVariantDataArrayString(m_value); }
1340
1341 protected:
1342     wxArrayString m_value;
1343 };
1344
1345 bool wxVariantDataArrayString::Eq(wxVariantData& data) const
1346 {
1347     wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
1348
1349     wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
1350
1351     return otherData.m_value == m_value;
1352 }
1353
1354 #if wxUSE_STD_IOSTREAM
1355 bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
1356 {
1357     // Not implemented
1358     return false;
1359 }
1360 #endif
1361
1362 bool wxVariantDataArrayString::Write(wxString& str) const
1363 {
1364     size_t count = m_value.GetCount();
1365     for ( size_t n = 0; n < count; n++ )
1366     {
1367         if ( n )
1368             str += _T(';');
1369
1370         str += m_value[n];
1371     }
1372
1373     return true;
1374 }
1375
1376
1377 #if wxUSE_STD_IOSTREAM
1378 bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
1379 {
1380     // Not implemented
1381     return false;
1382 }
1383 #endif
1384
1385
1386 bool wxVariantDataArrayString::Read(wxString& str)
1387 {
1388     wxStringTokenizer tk(str, _T(";"));
1389     while ( tk.HasMoreTokens() )
1390     {
1391         m_value.Add(tk.GetNextToken());
1392     }
1393
1394     return true;
1395 }
1396
1397 // wxVariant
1398
1399 wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1400 {
1401     m_data = new wxVariantDataArrayString(val);
1402     m_name = name;
1403 }
1404
1405 bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
1406 {
1407     wxFAIL_MSG( _T("TODO") );
1408
1409     return false;
1410 }
1411
1412 bool wxVariant::operator!=(const wxArrayString& value) const
1413 {
1414     return !(*this == value);
1415 }
1416
1417 void wxVariant::operator=(const wxArrayString& value)
1418 {
1419     if (GetType() == wxT("arrstring") &&
1420         m_data->GetRefCount() == 1)
1421     {
1422         ((wxVariantDataArrayString *)GetData())->SetValue(value);
1423     }
1424     else
1425     {
1426         UnRef();
1427         m_data = new wxVariantDataArrayString(value);
1428     }
1429 }
1430
1431 wxArrayString wxVariant::GetArrayString() const
1432 {
1433     if ( GetType() == wxT("arrstring") )
1434         return ((wxVariantDataArrayString *)GetData())->GetValue();
1435
1436     return wxArrayString();
1437 }
1438
1439 // ----------------------------------------------------------------------------
1440 // wxVariantDataList
1441 // ----------------------------------------------------------------------------
1442
1443 class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
1444 {
1445 public:
1446     wxVariantDataList() {}
1447     wxVariantDataList(const wxVariantList& list);
1448     virtual ~wxVariantDataList();
1449
1450     wxVariantList& GetValue() { return m_value; }
1451     void SetValue(const wxVariantList& value) ;
1452
1453     virtual bool Eq(wxVariantData& data) const;
1454 #if wxUSE_STD_IOSTREAM
1455     virtual bool Write(wxSTD ostream& str) const;
1456 #endif
1457     virtual bool Write(wxString& str) const;
1458 #if wxUSE_STD_IOSTREAM
1459     virtual bool Read(wxSTD istream& str);
1460 #endif
1461     virtual bool Read(wxString& str);
1462     virtual wxString GetType() const { return wxT("list"); }
1463
1464     void Clear();
1465
1466     wxVariantData* Clone() const { return new wxVariantDataList(m_value); }
1467 protected:
1468     wxVariantList  m_value;
1469 };
1470
1471 wxVariantDataList::wxVariantDataList(const wxVariantList& list)
1472 {
1473     SetValue(list);
1474 }
1475
1476 wxVariantDataList::~wxVariantDataList()
1477 {
1478     Clear();
1479 }
1480
1481 void wxVariantDataList::SetValue(const wxVariantList& value)
1482 {
1483     Clear();
1484     wxVariantList::compatibility_iterator node = value.GetFirst();
1485     while (node)
1486     {
1487         wxVariant* var = node->GetData();
1488         m_value.Append(new wxVariant(*var));
1489         node = node->GetNext();
1490     }
1491 }
1492
1493 void wxVariantDataList::Clear()
1494 {
1495     wxVariantList::compatibility_iterator node = m_value.GetFirst();
1496     while (node)
1497     {
1498         wxVariant* var = node->GetData();
1499         delete var;
1500         node = node->GetNext();
1501     }
1502     m_value.Clear();
1503 }
1504
1505 bool wxVariantDataList::Eq(wxVariantData& data) const
1506 {
1507     wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
1508
1509     wxVariantDataList& listData = (wxVariantDataList&) data;
1510     wxVariantList::compatibility_iterator node1 = m_value.GetFirst();
1511     wxVariantList::compatibility_iterator node2 = listData.GetValue().GetFirst();
1512     while (node1 && node2)
1513     {
1514         wxVariant* var1 = node1->GetData();
1515         wxVariant* var2 = node2->GetData();
1516         if ((*var1) != (*var2))
1517             return false;
1518         node1 = node1->GetNext();
1519         node2 = node2->GetNext();
1520     }
1521     if (node1 || node2) return false;
1522     return true;
1523 }
1524
1525 #if wxUSE_STD_IOSTREAM
1526 bool wxVariantDataList::Write(wxSTD ostream& str) const
1527 {
1528     wxString s;
1529     Write(s);
1530     str << (const char*) s.mb_str();
1531     return true;
1532 }
1533 #endif
1534
1535 bool wxVariantDataList::Write(wxString& str) const
1536 {
1537     str = wxEmptyString;
1538     wxVariantList::compatibility_iterator node = m_value.GetFirst();
1539     while (node)
1540     {
1541         wxVariant* var = node->GetData();
1542         if (node != m_value.GetFirst())
1543           str += wxT(" ");
1544         wxString str1;
1545         str += var->MakeString();
1546         node = node->GetNext();
1547     }
1548
1549     return true;
1550 }
1551
1552 #if wxUSE_STD_IOSTREAM
1553 bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
1554 {
1555     wxFAIL_MSG(wxT("Unimplemented"));
1556     // TODO
1557     return false;
1558 }
1559 #endif
1560
1561 bool wxVariantDataList::Read(wxString& WXUNUSED(str))
1562 {
1563     wxFAIL_MSG(wxT("Unimplemented"));
1564     // TODO
1565     return false;
1566 }
1567
1568 // wxVariant
1569
1570 wxVariant::wxVariant(const wxVariantList& val, const wxString& name) // List of variants
1571 {
1572     m_data = new wxVariantDataList(val);
1573     m_name = name;
1574 }
1575
1576 bool wxVariant::operator== (const wxVariantList& value) const
1577 {
1578     wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1579
1580     wxVariantDataList other(value);
1581     return (GetData()->Eq(other));
1582 }
1583
1584 bool wxVariant::operator!= (const wxVariantList& value) const
1585 {
1586     return (!((*this) == value));
1587 }
1588
1589 void wxVariant::operator= (const wxVariantList& value)
1590 {
1591     if (GetType() == wxT("list") &&
1592         m_data->GetRefCount() == 1)
1593     {
1594         ((wxVariantDataList*)GetData())->SetValue(value);
1595     }
1596     else
1597     {
1598         UnRef();
1599         m_data = new wxVariantDataList(value);
1600     }
1601 }
1602
1603 wxVariantList& wxVariant::GetList() const
1604 {
1605     wxASSERT( (GetType() == wxT("list")) );
1606
1607     return (wxVariantList&) ((wxVariantDataList*) m_data)->GetValue();
1608 }
1609
1610 // Make empty list
1611 void wxVariant::NullList()
1612 {
1613     SetData(new wxVariantDataList());
1614 }
1615
1616 // Append to list
1617 void wxVariant::Append(const wxVariant& value)
1618 {
1619     wxVariantList& list = GetList();
1620
1621     list.Append(new wxVariant(value));
1622 }
1623
1624 // Insert at front of list
1625 void wxVariant::Insert(const wxVariant& value)
1626 {
1627     wxVariantList& list = GetList();
1628
1629     list.Insert(new wxVariant(value));
1630 }
1631
1632 // Returns true if the variant is a member of the list
1633 bool wxVariant::Member(const wxVariant& value) const
1634 {
1635     wxVariantList& list = GetList();
1636
1637     wxVariantList::compatibility_iterator node = list.GetFirst();
1638     while (node)
1639     {
1640         wxVariant* other = node->GetData();
1641         if (value == *other)
1642             return true;
1643         node = node->GetNext();
1644     }
1645     return false;
1646 }
1647
1648 // Deletes the nth element of the list
1649 bool wxVariant::Delete(size_t item)
1650 {
1651     wxVariantList& list = GetList();
1652
1653     wxASSERT_MSG( (item < list.GetCount()), wxT("Invalid index to Delete") );
1654     wxVariantList::compatibility_iterator node = list.Item(item);
1655     wxVariant* variant = node->GetData();
1656     delete variant;
1657     list.Erase(node);
1658     return true;
1659 }
1660
1661 // Clear list
1662 void wxVariant::ClearList()
1663 {
1664     if (!IsNull() && (GetType() == wxT("list")))
1665     {
1666         ((wxVariantDataList*) m_data)->Clear();
1667     }
1668     else
1669     {
1670         if (!GetType().IsSameAs(wxT("list")))
1671             UnRef();
1672
1673         m_data = new wxVariantDataList;
1674     }
1675 }
1676
1677 // Treat a list variant as an array
1678 wxVariant wxVariant::operator[] (size_t idx) const
1679 {
1680     wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
1681
1682     if (GetType() == wxT("list"))
1683     {
1684         wxVariantDataList* data = (wxVariantDataList*) m_data;
1685         wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1686         return *(data->GetValue().Item(idx)->GetData());
1687     }
1688     return wxNullVariant;
1689 }
1690
1691 wxVariant& wxVariant::operator[] (size_t idx)
1692 {
1693     // We can't return a reference to a variant for a string list, since the string
1694     // is actually stored as a char*, not a variant.
1695
1696     wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1697
1698     wxVariantDataList* data = (wxVariantDataList*) m_data;
1699     wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1700
1701     return * (data->GetValue().Item(idx)->GetData());
1702 }
1703
1704 // Return the number of elements in a list
1705 size_t wxVariant::GetCount() const
1706 {
1707     wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
1708
1709     if (GetType() == wxT("list"))
1710     {
1711         wxVariantDataList* data = (wxVariantDataList*) m_data;
1712         return data->GetValue().GetCount();
1713     }
1714     return 0;
1715 }
1716
1717 // ----------------------------------------------------------------------------
1718 // Type conversion
1719 // ----------------------------------------------------------------------------
1720
1721 bool wxVariant::Convert(long* value) const
1722 {
1723     wxString type(GetType());
1724     if (type == wxT("double"))
1725         *value = (long) (((wxVariantDoubleData*)GetData())->GetValue());
1726     else if (type == wxT("long"))
1727         *value = ((wxVariantDataLong*)GetData())->GetValue();
1728 #ifdef HAVE_BOOL
1729     else if (type == wxT("bool"))
1730         *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
1731 #endif
1732     else if (type == wxT("string"))
1733         *value = wxAtol(((wxVariantDataString*)GetData())->GetValue());
1734     else
1735         return false;
1736
1737     return true;
1738 }
1739
1740 bool wxVariant::Convert(bool* value) const
1741 {
1742     wxString type(GetType());
1743     if (type == wxT("double"))
1744         *value = ((int) (((wxVariantDoubleData*)GetData())->GetValue()) != 0);
1745     else if (type == wxT("long"))
1746         *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
1747 #ifdef HAVE_BOOL
1748     else if (type == wxT("bool"))
1749         *value = ((wxVariantDataBool*)GetData())->GetValue();
1750 #endif
1751     else if (type == wxT("string"))
1752     {
1753         wxString val(((wxVariantDataString*)GetData())->GetValue());
1754         val.MakeLower();
1755         if (val == wxT("true") || val == wxT("yes") || val == wxT('1') )
1756             *value = true;
1757         else if (val == wxT("false") || val == wxT("no") || val == wxT('0') )
1758             *value = false;
1759         else
1760             return false;
1761     }
1762     else
1763         return false;
1764
1765     return true;
1766 }
1767
1768 bool wxVariant::Convert(double* value) const
1769 {
1770     wxString type(GetType());
1771     if (type == wxT("double"))
1772         *value = ((wxVariantDoubleData*)GetData())->GetValue();
1773     else if (type == wxT("long"))
1774         *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
1775 #ifdef HAVE_BOOL
1776     else if (type == wxT("bool"))
1777         *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
1778 #endif
1779     else if (type == wxT("string"))
1780         *value = (double) wxAtof(((wxVariantDataString*)GetData())->GetValue());
1781     else
1782         return false;
1783
1784     return true;
1785 }
1786
1787 bool wxVariant::Convert(wxUniChar* value) const
1788 {
1789     wxString type(GetType());
1790     if (type == wxT("char"))
1791         *value = ((wxVariantDataChar*)GetData())->GetValue();
1792     else if (type == wxT("long"))
1793         *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
1794 #ifdef HAVE_BOOL
1795     else if (type == wxT("bool"))
1796         *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
1797 #endif
1798     else
1799         return false;
1800
1801     return true;
1802 }
1803
1804 bool wxVariant::Convert(char* value) const
1805 {
1806     wxUniChar ch;
1807     if ( !Convert(&ch) )
1808         return false;
1809     *value = ch;
1810     return true;
1811 }
1812
1813 bool wxVariant::Convert(wchar_t* value) const
1814 {
1815     wxUniChar ch;
1816     if ( !Convert(&ch) )
1817         return false;
1818     *value = ch;
1819     return true;
1820 }
1821
1822 bool wxVariant::Convert(wxString* value) const
1823 {
1824     *value = MakeString();
1825     return true;
1826 }
1827
1828 #if wxUSE_DATETIME
1829 bool wxVariant::Convert(wxDateTime* value) const
1830 {
1831     wxString type(GetType());
1832     if (type == wxT("datetime"))
1833     {
1834         *value = ((wxVariantDataDateTime*)GetData())->GetValue();
1835         return true;
1836     }
1837     // Fallback to string conversion
1838     wxString val;
1839     return Convert(&val) &&
1840                 (value->ParseDateTime(val.c_str()/*FIXME-UTF8*/) ||
1841                  value->ParseDate(val.c_str()/*FIXME-UTF8*/) ||
1842                  value->ParseTime(val.c_str()/*FIXME-UTF8*/));
1843 }
1844 #endif // wxUSE_DATETIME
1845
1846 #endif // wxUSE_VARIANT