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