]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/variant.cpp
no changes, just a typo fix
[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(const wxUniChar& value) { m_value = value; }
647
648 inline wxUniChar GetValue() const { return m_value; }
649 inline void SetValue(const wxUniChar& 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 wxUniChar 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 str << wxString(m_value);
683 return true;
684}
685#endif
686
687bool wxVariantDataChar::Write(wxString& str) const
688{
689 str = m_value;
690 return true;
691}
692
693#if wxUSE_STD_IOSTREAM
694bool wxVariantDataChar::Read(wxSTD istream& WXUNUSED(str))
695{
696 wxFAIL_MSG(wxT("Unimplemented"));
697
698 return false;
699}
700#endif
701
702#if wxUSE_STREAMS
703bool wxVariantDataChar::Write(wxOutputStream& str) const
704{
705 wxTextOutputStream s(str);
706
707 // FIXME-UTF8: this should be just "s << m_value;" after removal of
708 // ANSI build and addition of wxUniChar to wxTextOutputStream:
709 s << (wxChar)m_value;
710
711 return true;
712}
713
714bool wxVariantDataChar::Read(wxInputStream& str)
715{
716 wxTextInputStream s(str);
717
718 // FIXME-UTF8: this should be just "s >> m_value;" after removal of
719 // ANSI build and addition of wxUniChar to wxTextInputStream:
720 wxChar ch;
721 s >> ch;
722 m_value = ch;
723
724 return true;
725}
726#endif // wxUSE_STREAMS
727
728bool wxVariantDataChar::Read(wxString& str)
729{
730 m_value = str[0u];
731 return true;
732}
733
734wxVariant::wxVariant(const wxUniChar& val, const wxString& name)
735{
736 m_data = new wxVariantDataChar(val);
737 m_name = name;
738}
739
740wxVariant::wxVariant(char val, const wxString& name)
741{
742 m_data = new wxVariantDataChar(val);
743 m_name = name;
744}
745
746wxVariant::wxVariant(wchar_t val, const wxString& name)
747{
748 m_data = new wxVariantDataChar(val);
749 m_name = name;
750}
751
752bool wxVariant::operator==(const wxUniChar& value) const
753{
754 wxUniChar thisValue;
755 if (!Convert(&thisValue))
756 return false;
757 else
758 return (value == thisValue);
759}
760
761wxVariant& wxVariant::operator=(const wxUniChar& value)
762{
763 if (GetType() == wxT("char") &&
764 m_data->GetRefCount() == 1)
765 {
766 ((wxVariantDataChar*)GetData())->SetValue(value);
767 }
768 else
769 {
770 UnRef();
771 m_data = new wxVariantDataChar(value);
772 }
773
774 return *this;
775}
776
777wxUniChar wxVariant::GetChar() const
778{
779 wxUniChar value;
780 if (Convert(& value))
781 return value;
782 else
783 {
784 wxFAIL_MSG(wxT("Could not convert to a char"));
785 return wxUniChar(0);
786 }
787}
788
789// ----------------------------------------------------------------------------
790// wxVariantDataString
791// ----------------------------------------------------------------------------
792
793class WXDLLIMPEXP_BASE wxVariantDataString: public wxVariantData
794{
795DECLARE_DYNAMIC_CLASS(wxVariantDataString)
796public:
797 wxVariantDataString() { }
798 wxVariantDataString(const wxString& value) { m_value = value; }
799
800 inline wxString GetValue() const { return m_value; }
801 inline void SetValue(const wxString& value) { m_value = value; }
802
803 virtual bool Eq(wxVariantData& data) const;
804#if wxUSE_STD_IOSTREAM
805 virtual bool Write(wxSTD ostream& str) const;
806#endif
807 virtual bool Read(wxString& str);
808 virtual bool Write(wxString& str) const;
809#if wxUSE_STD_IOSTREAM
810 virtual bool Read(wxSTD istream& WXUNUSED(str)) { return false; }
811#endif
812#if wxUSE_STREAMS
813 virtual bool Read(wxInputStream& str);
814 virtual bool Write(wxOutputStream& str) const;
815#endif // wxUSE_STREAMS
816 virtual wxString GetType() const { return wxT("string"); }
817
818protected:
819 wxString m_value;
820};
821
822bool wxVariantDataString::Eq(wxVariantData& data) const
823{
824 wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
825
826 wxVariantDataString& otherData = (wxVariantDataString&) data;
827
828 return (otherData.m_value == m_value);
829}
830
831#if wxUSE_STD_IOSTREAM
832bool wxVariantDataString::Write(wxSTD ostream& str) const
833{
834 str << (const char*) m_value.mb_str();
835 return true;
836}
837#endif
838
839bool wxVariantDataString::Write(wxString& str) const
840{
841 str = m_value;
842 return true;
843}
844
845#if wxUSE_STREAMS
846bool wxVariantDataString::Write(wxOutputStream& str) const
847{
848 // why doesn't wxOutputStream::operator<< take "const wxString&"
849 wxTextOutputStream s(str);
850 s.WriteString(m_value);
851 return true;
852}
853
854bool wxVariantDataString::Read(wxInputStream& str)
855{
856 wxTextInputStream s(str);
857
858 m_value = s.ReadLine();
859 return true;
860}
861#endif // wxUSE_STREAMS
862
863bool wxVariantDataString::Read(wxString& str)
864{
865 m_value = str;
866 return true;
867}
868
869IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
870
871// wxVariant ****
872
873wxVariant::wxVariant(const wxString& val, const wxString& name)
874{
875 m_data = new wxVariantDataString(val);
876 m_name = name;
877}
878
879wxVariant::wxVariant(const char* val, const wxString& name)
880{
881 m_data = new wxVariantDataString(wxString(val));
882 m_name = name;
883}
884
885wxVariant::wxVariant(const wchar_t* val, const wxString& name)
886{
887 m_data = new wxVariantDataString(wxString(val));
888 m_name = name;
889}
890
891wxVariant::wxVariant(const wxCStrData& val, const wxString& name)
892{
893 m_data = new wxVariantDataString(val.AsString());
894 m_name = name;
895}
896
897wxVariant::wxVariant(const wxCharBuffer& val, const wxString& name)
898{
899 m_data = new wxVariantDataString(wxString(val));
900 m_name = name;
901}
902
903wxVariant::wxVariant(const wxWCharBuffer& val, const wxString& name)
904{
905 m_data = new wxVariantDataString(wxString(val));
906 m_name = name;
907}
908
909bool wxVariant::operator== (const wxString& value) const
910{
911 wxString thisValue;
912 if (!Convert(&thisValue))
913 return false;
914
915 return value == thisValue;
916}
917
918bool wxVariant::operator!= (const wxString& value) const
919{
920 return (!((*this) == value));
921}
922
923wxVariant& wxVariant::operator= (const wxString& value)
924{
925 if (GetType() == wxT("string") &&
926 m_data->GetRefCount() == 1)
927 {
928 ((wxVariantDataString*)GetData())->SetValue(value);
929 }
930 else
931 {
932 UnRef();
933 m_data = new wxVariantDataString(value);
934 }
935 return *this;
936}
937
938wxString wxVariant::GetString() const
939{
940 wxString value;
941 if (!Convert(& value))
942 {
943 wxFAIL_MSG(wxT("Could not convert to a string"));
944 }
945
946 return value;
947}
948
949// ----------------------------------------------------------------------------
950// wxVariantDataWxObjectPtr
951// ----------------------------------------------------------------------------
952
953class wxVariantDataWxObjectPtr: public wxVariantData
954{
955DECLARE_DYNAMIC_CLASS(wxVariantDataWxObjectPtr)
956public:
957 wxVariantDataWxObjectPtr() { }
958 wxVariantDataWxObjectPtr(wxObject* value) { m_value = value; }
959
960 inline wxObject* GetValue() const { return m_value; }
961 inline void SetValue(wxObject* value) { m_value = value; }
962
963 virtual bool Eq(wxVariantData& data) const;
964#if wxUSE_STD_IOSTREAM
965 virtual bool Write(wxSTD ostream& str) const;
966#endif
967 virtual bool Write(wxString& str) const;
968#if wxUSE_STD_IOSTREAM
969 virtual bool Read(wxSTD istream& str);
970#endif
971 virtual bool Read(wxString& str);
972 virtual wxString GetType() const ;
973 virtual wxVariantData* Clone() { return new wxVariantDataWxObjectPtr; }
974
975 virtual wxClassInfo* GetValueClassInfo() ;
976protected:
977 wxObject* m_value;
978
979 DECLARE_NO_COPY_CLASS(wxVariantDataWxObjectPtr)
980};
981
982IMPLEMENT_DYNAMIC_CLASS(wxVariantDataWxObjectPtr, wxVariantData)
983
984bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const
985{
986 wxASSERT_MSG( wxIsKindOf((&data), wxVariantDataWxObjectPtr), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
987
988 wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
989
990 return (otherData.m_value == m_value);
991}
992
993wxString wxVariantDataWxObjectPtr::GetType() const
994{
995 wxString returnVal(wxT("wxObject"));
996 if (m_value) {
997 returnVal = m_value->GetClassInfo()->GetClassName();
998 }
999 return returnVal;
1000}
1001
1002wxClassInfo* wxVariantDataWxObjectPtr::GetValueClassInfo()
1003{
1004 wxClassInfo* returnVal=NULL;
1005
1006 if (m_value) returnVal = m_value->GetClassInfo();
1007
1008 return returnVal;
1009}
1010
1011#if wxUSE_STD_IOSTREAM
1012bool wxVariantDataWxObjectPtr::Write(wxSTD ostream& str) const
1013{
1014 wxString s;
1015 Write(s);
1016 str << (const char*) s.mb_str();
1017 return true;
1018}
1019#endif
1020
1021bool wxVariantDataWxObjectPtr::Write(wxString& str) const
1022{
1023 str.Printf(wxT("%s(%p)"), GetType().c_str(), wx_static_cast(void*, m_value));
1024 return true;
1025}
1026
1027#if wxUSE_STD_IOSTREAM
1028bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
1029{
1030 // Not implemented
1031 return false;
1032}
1033#endif
1034
1035bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
1036{
1037 // Not implemented
1038 return false;
1039}
1040
1041// wxVariant
1042
1043wxVariant::wxVariant( wxObject* val, const wxString& name)
1044{
1045 m_data = new wxVariantDataWxObjectPtr(val);
1046 m_name = name;
1047}
1048
1049bool wxVariant::operator== (wxObject* value) const
1050{
1051 return (value == ((wxVariantDataWxObjectPtr*)GetData())->GetValue());
1052}
1053
1054bool wxVariant::operator!= (wxObject* value) const
1055{
1056 return (!((*this) == (wxObject*) value));
1057}
1058
1059void wxVariant::operator= (wxObject* value)
1060{
1061 UnRef();
1062 m_data = new wxVariantDataWxObjectPtr(value);
1063}
1064
1065wxObject* wxVariant::GetWxObjectPtr() const
1066{
1067 wxASSERT(wxIsKindOf(GetData(), wxVariantDataWxObjectPtr));
1068 return (wxObject*) ((wxVariantDataWxObjectPtr*) m_data)->GetValue();
1069}
1070
1071// ----------------------------------------------------------------------------
1072// wxVariantDataVoidPtr
1073// ----------------------------------------------------------------------------
1074
1075class wxVariantDataVoidPtr: public wxVariantData
1076{
1077DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
1078public:
1079 wxVariantDataVoidPtr() { }
1080 wxVariantDataVoidPtr(void* value) { m_value = value; }
1081
1082 inline void* GetValue() const { return m_value; }
1083 inline void SetValue(void* value) { m_value = value; }
1084
1085 virtual bool Eq(wxVariantData& data) const;
1086#if wxUSE_STD_IOSTREAM
1087 virtual bool Write(wxSTD ostream& str) const;
1088#endif
1089 virtual bool Write(wxString& str) const;
1090#if wxUSE_STD_IOSTREAM
1091 virtual bool Read(wxSTD istream& str);
1092#endif
1093 virtual bool Read(wxString& str);
1094 virtual wxString GetType() const { return wxT("void*"); }
1095 virtual wxVariantData* Clone() { return new wxVariantDataVoidPtr; }
1096
1097protected:
1098 void* m_value;
1099
1100 DECLARE_NO_COPY_CLASS(wxVariantDataVoidPtr)
1101};
1102
1103IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
1104
1105bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
1106{
1107 wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
1108
1109 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
1110
1111 return (otherData.m_value == m_value);
1112}
1113
1114#if wxUSE_STD_IOSTREAM
1115bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
1116{
1117 wxString s;
1118 Write(s);
1119 str << (const char*) s.mb_str();
1120 return true;
1121}
1122#endif
1123
1124bool wxVariantDataVoidPtr::Write(wxString& str) const
1125{
1126 str.Printf(wxT("%p"), m_value);
1127 return true;
1128}
1129
1130#if wxUSE_STD_IOSTREAM
1131bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
1132{
1133 // Not implemented
1134 return false;
1135}
1136#endif
1137
1138bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
1139{
1140 // Not implemented
1141 return false;
1142}
1143
1144// wxVariant
1145
1146wxVariant::wxVariant( void* val, const wxString& name)
1147{
1148 m_data = new wxVariantDataVoidPtr(val);
1149 m_name = name;
1150}
1151
1152bool wxVariant::operator== (void* value) const
1153{
1154 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
1155}
1156
1157bool wxVariant::operator!= (void* value) const
1158{
1159 return (!((*this) == (void*) value));
1160}
1161
1162void wxVariant::operator= (void* value)
1163{
1164 if (GetType() == wxT("void*") &&
1165 m_data->GetRefCount() == 1)
1166 {
1167 ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1168 }
1169 else
1170 {
1171 UnRef();
1172 m_data = new wxVariantDataVoidPtr(value);
1173 }
1174}
1175
1176void* wxVariant::GetVoidPtr() const
1177{
1178 wxASSERT( (GetType() == wxT("void*")) );
1179
1180 return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
1181}
1182
1183// ----------------------------------------------------------------------------
1184// wxVariantDataDateTime
1185// ----------------------------------------------------------------------------
1186
1187#if wxUSE_DATETIME
1188
1189class wxVariantDataDateTime: public wxVariantData
1190{
1191 DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime)
1192
1193public:
1194 wxVariantDataDateTime() { }
1195 wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
1196#if wxUSE_ODBC
1197 wxVariantDataDateTime(const TIME_STRUCT* valptr)
1198 { m_value = wxDateTime(valptr->hour, valptr->minute, valptr->second); }
1199 wxVariantDataDateTime(const DATE_STRUCT* valptr)
1200 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1),valptr->year); }
1201 wxVariantDataDateTime(const TIMESTAMP_STRUCT* valptr)
1202 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1), valptr->year,
1203 valptr->hour, valptr->minute, valptr->second, (wxDateTime::wxDateTime_t)valptr->fraction ); }
1204#endif //ODBC
1205
1206 inline wxDateTime GetValue() const { return m_value; }
1207 inline void SetValue(const wxDateTime& value) { m_value = value; }
1208
1209 virtual bool Eq(wxVariantData& data) const;
1210#if wxUSE_STD_IOSTREAM
1211 virtual bool Write(wxSTD ostream& str) const;
1212#endif
1213 virtual bool Write(wxString& str) const;
1214#if wxUSE_STD_IOSTREAM
1215 virtual bool Read(wxSTD istream& str);
1216#endif
1217 virtual bool Read(wxString& str);
1218 virtual wxString GetType() const { return wxT("datetime"); }
1219 virtual wxVariantData* Clone() { return new wxVariantDataDateTime; }
1220
1221protected:
1222 wxDateTime m_value;
1223};
1224
1225
1226IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime, wxVariantData)
1227
1228bool wxVariantDataDateTime::Eq(wxVariantData& data) const
1229{
1230 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
1231
1232 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1233
1234 return (otherData.m_value == m_value);
1235}
1236
1237
1238#if wxUSE_STD_IOSTREAM
1239bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
1240{
1241 wxString value;
1242 Write( value );
1243 str << value.c_str();
1244 return true;
1245}
1246#endif
1247
1248
1249bool wxVariantDataDateTime::Write(wxString& str) const
1250{
1251 str = m_value.Format();
1252 return true;
1253}
1254
1255
1256#if wxUSE_STD_IOSTREAM
1257bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
1258{
1259 // Not implemented
1260 return false;
1261}
1262#endif
1263
1264
1265bool wxVariantDataDateTime::Read(wxString& str)
1266{
1267 if(! m_value.ParseDateTime(str.c_str()/*FIXME-UTF8*/))
1268 return false;
1269 return true;
1270}
1271
1272// wxVariant
1273
1274wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1275{
1276 m_data = new wxVariantDataDateTime(val);
1277 m_name = name;
1278}
1279
1280#if wxUSE_ODBC
1281wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1282{
1283 m_data = new wxVariantDataDateTime(valptr);
1284 m_name = name;
1285}
1286
1287wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1288{
1289 m_data = new wxVariantDataDateTime(valptr);
1290 m_name = name;
1291}
1292
1293wxVariant::wxVariant(const DATE_STRUCT* valptr, const wxString& name) // Date
1294{
1295 m_data = new wxVariantDataDateTime(valptr);
1296 m_name = name;
1297}
1298#endif // wxUSE_ODBC
1299
1300bool wxVariant::operator== (const wxDateTime& value) const
1301{
1302 wxDateTime thisValue;
1303 if (!Convert(&thisValue))
1304 return false;
1305
1306 return value.IsEqualTo(thisValue);
1307}
1308
1309bool wxVariant::operator!= (const wxDateTime& value) const
1310{
1311 return (!((*this) == value));
1312}
1313
1314void wxVariant::operator= (const wxDateTime& value)
1315{
1316 if (GetType() == wxT("datetime") &&
1317 m_data->GetRefCount() == 1)
1318 {
1319 ((wxVariantDataDateTime*)GetData())->SetValue(value);
1320 }
1321 else
1322 {
1323 UnRef();
1324 m_data = new wxVariantDataDateTime(value);
1325 }
1326}
1327
1328#if wxUSE_ODBC
1329void wxVariant::operator= (const DATE_STRUCT* value)
1330{
1331 UnRef();
1332 m_data = new wxVariantDataDateTime(value);
1333}
1334
1335void wxVariant::operator= (const TIME_STRUCT* value)
1336{
1337 UnRef();
1338 m_data = new wxVariantDataDateTime(value);
1339}
1340
1341void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
1342{
1343 UnRef();
1344 m_data = new wxVariantDataDateTime(value);
1345}
1346
1347#endif // wxUSE_ODBC
1348
1349wxDateTime wxVariant::GetDateTime() const
1350{
1351 wxDateTime value;
1352 if (!Convert(& value))
1353 {
1354 wxFAIL_MSG(wxT("Could not convert to a datetime"));
1355 }
1356
1357 return value;
1358}
1359
1360#endif // wxUSE_DATETIME
1361
1362// ----------------------------------------------------------------------------
1363// wxVariantDataArrayString
1364// ----------------------------------------------------------------------------
1365
1366class wxVariantDataArrayString: public wxVariantData
1367{
1368public:
1369 wxVariantDataArrayString() { }
1370 wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
1371
1372 wxArrayString GetValue() const { return m_value; }
1373 void SetValue(const wxArrayString& value) { m_value = value; }
1374
1375 virtual bool Eq(wxVariantData& data) const;
1376#if wxUSE_STD_IOSTREAM
1377 virtual bool Write(wxSTD ostream& str) const;
1378#endif
1379 virtual bool Write(wxString& str) const;
1380#if wxUSE_STD_IOSTREAM
1381 virtual bool Read(wxSTD istream& str);
1382#endif
1383 virtual bool Read(wxString& str);
1384 virtual wxString GetType() const { return wxT("arrstring"); }
1385 virtual wxVariantData* Clone() { return new wxVariantDataArrayString; }
1386
1387protected:
1388 wxArrayString m_value;
1389
1390 DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString)
1391};
1392
1393IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString, wxVariantData)
1394
1395bool wxVariantDataArrayString::Eq(wxVariantData& data) const
1396{
1397 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
1398
1399 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
1400
1401 return otherData.m_value == m_value;
1402}
1403
1404#if wxUSE_STD_IOSTREAM
1405bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
1406{
1407 // Not implemented
1408 return false;
1409}
1410#endif
1411
1412bool wxVariantDataArrayString::Write(wxString& str) const
1413{
1414 size_t count = m_value.GetCount();
1415 for ( size_t n = 0; n < count; n++ )
1416 {
1417 if ( n )
1418 str += _T(';');
1419
1420 str += m_value[n];
1421 }
1422
1423 return true;
1424}
1425
1426
1427#if wxUSE_STD_IOSTREAM
1428bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
1429{
1430 // Not implemented
1431 return false;
1432}
1433#endif
1434
1435
1436bool wxVariantDataArrayString::Read(wxString& str)
1437{
1438 wxStringTokenizer tk(str, _T(";"));
1439 while ( tk.HasMoreTokens() )
1440 {
1441 m_value.Add(tk.GetNextToken());
1442 }
1443
1444 return true;
1445}
1446
1447// wxVariant
1448
1449wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1450{
1451 m_data = new wxVariantDataArrayString(val);
1452 m_name = name;
1453}
1454
1455bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
1456{
1457 wxFAIL_MSG( _T("TODO") );
1458
1459 return false;
1460}
1461
1462bool wxVariant::operator!=(const wxArrayString& value) const
1463{
1464 return !(*this == value);
1465}
1466
1467void wxVariant::operator=(const wxArrayString& value)
1468{
1469 if (GetType() == wxT("arrstring") &&
1470 m_data->GetRefCount() == 1)
1471 {
1472 ((wxVariantDataArrayString *)GetData())->SetValue(value);
1473 }
1474 else
1475 {
1476 UnRef();
1477 m_data = new wxVariantDataArrayString(value);
1478 }
1479}
1480
1481wxArrayString wxVariant::GetArrayString() const
1482{
1483 if ( GetType() == wxT("arrstring") )
1484 return ((wxVariantDataArrayString *)GetData())->GetValue();
1485
1486 return wxArrayString();
1487}
1488
1489// ----------------------------------------------------------------------------
1490// wxVariantDataList
1491// ----------------------------------------------------------------------------
1492
1493class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
1494{
1495DECLARE_DYNAMIC_CLASS(wxVariantDataList)
1496public:
1497 wxVariantDataList() {}
1498 wxVariantDataList(const wxList& list);
1499 virtual ~wxVariantDataList();
1500
1501 wxList& GetValue() { return m_value; }
1502 void SetValue(const wxList& value) ;
1503
1504 virtual bool Eq(wxVariantData& data) const;
1505#if wxUSE_STD_IOSTREAM
1506 virtual bool Write(wxSTD ostream& str) const;
1507#endif
1508 virtual bool Write(wxString& str) const;
1509#if wxUSE_STD_IOSTREAM
1510 virtual bool Read(wxSTD istream& str);
1511#endif
1512 virtual bool Read(wxString& str);
1513 virtual wxString GetType() const { return wxT("list"); }
1514
1515 void Clear();
1516
1517protected:
1518 wxList m_value;
1519};
1520
1521IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
1522
1523wxVariantDataList::wxVariantDataList(const wxList& list)
1524{
1525 SetValue(list);
1526}
1527
1528wxVariantDataList::~wxVariantDataList()
1529{
1530 Clear();
1531}
1532
1533void wxVariantDataList::SetValue(const wxList& value)
1534{
1535 Clear();
1536 wxList::compatibility_iterator node = value.GetFirst();
1537 while (node)
1538 {
1539 wxVariant* var = (wxVariant*) node->GetData();
1540 m_value.Append(new wxVariant(*var));
1541 node = node->GetNext();
1542 }
1543}
1544
1545void wxVariantDataList::Clear()
1546{
1547 wxList::compatibility_iterator node = m_value.GetFirst();
1548 while (node)
1549 {
1550 wxVariant* var = (wxVariant*) node->GetData();
1551 delete var;
1552 node = node->GetNext();
1553 }
1554 m_value.Clear();
1555}
1556
1557bool wxVariantDataList::Eq(wxVariantData& data) const
1558{
1559 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
1560
1561 wxVariantDataList& listData = (wxVariantDataList&) data;
1562 wxList::compatibility_iterator node1 = m_value.GetFirst();
1563 wxList::compatibility_iterator node2 = listData.GetValue().GetFirst();
1564 while (node1 && node2)
1565 {
1566 wxVariant* var1 = (wxVariant*) node1->GetData();
1567 wxVariant* var2 = (wxVariant*) node2->GetData();
1568 if ((*var1) != (*var2))
1569 return false;
1570 node1 = node1->GetNext();
1571 node2 = node2->GetNext();
1572 }
1573 if (node1 || node2) return false;
1574 return true;
1575}
1576
1577#if wxUSE_STD_IOSTREAM
1578bool wxVariantDataList::Write(wxSTD ostream& str) const
1579{
1580 wxString s;
1581 Write(s);
1582 str << (const char*) s.mb_str();
1583 return true;
1584}
1585#endif
1586
1587bool wxVariantDataList::Write(wxString& str) const
1588{
1589 str = wxEmptyString;
1590 wxList::compatibility_iterator node = m_value.GetFirst();
1591 while (node)
1592 {
1593 wxVariant* var = (wxVariant*) node->GetData();
1594 if (node != m_value.GetFirst())
1595 str += wxT(" ");
1596 wxString str1;
1597 str += var->MakeString();
1598 node = node->GetNext();
1599 }
1600
1601 return true;
1602}
1603
1604#if wxUSE_STD_IOSTREAM
1605bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
1606{
1607 wxFAIL_MSG(wxT("Unimplemented"));
1608 // TODO
1609 return false;
1610}
1611#endif
1612
1613bool wxVariantDataList::Read(wxString& WXUNUSED(str))
1614{
1615 wxFAIL_MSG(wxT("Unimplemented"));
1616 // TODO
1617 return false;
1618}
1619
1620// wxVariant
1621
1622wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
1623{
1624 m_data = new wxVariantDataList(val);
1625 m_name = name;
1626}
1627
1628bool wxVariant::operator== (const wxList& value) const
1629{
1630 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1631
1632 wxVariantDataList other(value);
1633 return (GetData()->Eq(other));
1634}
1635
1636bool wxVariant::operator!= (const wxList& value) const
1637{
1638 return (!((*this) == value));
1639}
1640
1641void wxVariant::operator= (const wxList& value)
1642{
1643 if (GetType() == wxT("list") &&
1644 m_data->GetRefCount() == 1)
1645 {
1646 ((wxVariantDataList*)GetData())->SetValue(value);
1647 }
1648 else
1649 {
1650 UnRef();
1651 m_data = new wxVariantDataList(value);
1652 }
1653}
1654
1655wxList& wxVariant::GetList() const
1656{
1657 wxASSERT( (GetType() == wxT("list")) );
1658
1659 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1660}
1661
1662// Make empty list
1663void wxVariant::NullList()
1664{
1665 SetData(new wxVariantDataList());
1666}
1667
1668// Append to list
1669void wxVariant::Append(const wxVariant& value)
1670{
1671 wxList& list = GetList();
1672
1673 list.Append(new wxVariant(value));
1674}
1675
1676// Insert at front of list
1677void wxVariant::Insert(const wxVariant& value)
1678{
1679 wxList& list = GetList();
1680
1681 list.Insert(new wxVariant(value));
1682}
1683
1684// Returns true if the variant is a member of the list
1685bool wxVariant::Member(const wxVariant& value) const
1686{
1687 wxList& list = GetList();
1688
1689 wxList::compatibility_iterator node = list.GetFirst();
1690 while (node)
1691 {
1692 wxVariant* other = (wxVariant*) node->GetData();
1693 if (value == *other)
1694 return true;
1695 node = node->GetNext();
1696 }
1697 return false;
1698}
1699
1700// Deletes the nth element of the list
1701bool wxVariant::Delete(size_t item)
1702{
1703 wxList& list = GetList();
1704
1705 wxASSERT_MSG( (item < list.GetCount()), wxT("Invalid index to Delete") );
1706 wxList::compatibility_iterator node = list.Item(item);
1707 wxVariant* variant = (wxVariant*) node->GetData();
1708 delete variant;
1709 list.Erase(node);
1710 return true;
1711}
1712
1713// Clear list
1714void wxVariant::ClearList()
1715{
1716 if (!IsNull() && (GetType() == wxT("list")))
1717 {
1718 ((wxVariantDataList*) m_data)->Clear();
1719 }
1720 else
1721 {
1722 if (!GetType().IsSameAs(wxT("list")))
1723 UnRef();
1724
1725 m_data = new wxVariantDataList;
1726 }
1727}
1728
1729// Treat a list variant as an array
1730wxVariant wxVariant::operator[] (size_t idx) const
1731{
1732 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
1733
1734 if (GetType() == wxT("list"))
1735 {
1736 wxVariantDataList* data = (wxVariantDataList*) m_data;
1737 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1738 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1739 }
1740 return wxNullVariant;
1741}
1742
1743wxVariant& wxVariant::operator[] (size_t idx)
1744{
1745 // We can't return a reference to a variant for a string list, since the string
1746 // is actually stored as a char*, not a variant.
1747
1748 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1749
1750 wxVariantDataList* data = (wxVariantDataList*) m_data;
1751 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1752
1753 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1754}
1755
1756// Return the number of elements in a list
1757size_t wxVariant::GetCount() const
1758{
1759 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
1760
1761 if (GetType() == wxT("list"))
1762 {
1763 wxVariantDataList* data = (wxVariantDataList*) m_data;
1764 return data->GetValue().GetCount();
1765 }
1766 return 0;
1767}
1768
1769// ----------------------------------------------------------------------------
1770// Type conversion
1771// ----------------------------------------------------------------------------
1772
1773bool wxVariant::Convert(long* value) const
1774{
1775 wxString type(GetType());
1776 if (type == wxT("double"))
1777 *value = (long) (((wxVariantDoubleData*)GetData())->GetValue());
1778 else if (type == wxT("long"))
1779 *value = ((wxVariantDataLong*)GetData())->GetValue();
1780#ifdef HAVE_BOOL
1781 else if (type == wxT("bool"))
1782 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
1783#endif
1784 else if (type == wxT("string"))
1785 *value = wxAtol(((wxVariantDataString*)GetData())->GetValue());
1786 else
1787 return false;
1788
1789 return true;
1790}
1791
1792bool wxVariant::Convert(bool* value) const
1793{
1794 wxString type(GetType());
1795 if (type == wxT("double"))
1796 *value = ((int) (((wxVariantDoubleData*)GetData())->GetValue()) != 0);
1797 else if (type == wxT("long"))
1798 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
1799#ifdef HAVE_BOOL
1800 else if (type == wxT("bool"))
1801 *value = ((wxVariantDataBool*)GetData())->GetValue();
1802#endif
1803 else if (type == wxT("string"))
1804 {
1805 wxString val(((wxVariantDataString*)GetData())->GetValue());
1806 val.MakeLower();
1807 if (val == wxT("true") || val == wxT("yes") || val == wxT('1') )
1808 *value = true;
1809 else if (val == wxT("false") || val == wxT("no") || val == wxT('0') )
1810 *value = false;
1811 else
1812 return false;
1813 }
1814 else
1815 return false;
1816
1817 return true;
1818}
1819
1820bool wxVariant::Convert(double* value) const
1821{
1822 wxString type(GetType());
1823 if (type == wxT("double"))
1824 *value = ((wxVariantDoubleData*)GetData())->GetValue();
1825 else if (type == wxT("long"))
1826 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
1827#ifdef HAVE_BOOL
1828 else if (type == wxT("bool"))
1829 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
1830#endif
1831 else if (type == wxT("string"))
1832 *value = (double) wxAtof(((wxVariantDataString*)GetData())->GetValue());
1833 else
1834 return false;
1835
1836 return true;
1837}
1838
1839bool wxVariant::Convert(wxUniChar* value) const
1840{
1841 wxString type(GetType());
1842 if (type == wxT("char"))
1843 *value = ((wxVariantDataChar*)GetData())->GetValue();
1844 else if (type == wxT("long"))
1845 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
1846#ifdef HAVE_BOOL
1847 else if (type == wxT("bool"))
1848 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
1849#endif
1850 else
1851 return false;
1852
1853 return true;
1854}
1855
1856bool wxVariant::Convert(char* value) const
1857{
1858 wxUniChar ch;
1859 if ( !Convert(&ch) )
1860 return false;
1861 *value = ch;
1862 return true;
1863}
1864
1865bool wxVariant::Convert(wchar_t* value) const
1866{
1867 wxUniChar ch;
1868 if ( !Convert(&ch) )
1869 return false;
1870 *value = ch;
1871 return true;
1872}
1873
1874bool wxVariant::Convert(wxString* value) const
1875{
1876 *value = MakeString();
1877 return true;
1878}
1879
1880#if wxUSE_DATETIME
1881bool wxVariant::Convert(wxDateTime* value) const
1882{
1883 wxString type(GetType());
1884 if (type == wxT("datetime"))
1885 {
1886 *value = ((wxVariantDataDateTime*)GetData())->GetValue();
1887 return true;
1888 }
1889 // Fallback to string conversion
1890 wxString val;
1891 return Convert(&val) &&
1892 (value->ParseDateTime(val.c_str()/*FIXME-UTF8*/) ||
1893 value->ParseDate(val.c_str()/*FIXME-UTF8*/) ||
1894 value->ParseTime(val.c_str()/*FIXME-UTF8*/));
1895}
1896#endif // wxUSE_DATETIME
1897
1898#endif // wxUSE_VARIANT