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