fixed to make wxVariant compatible with both ANSI and Unicode modes
[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 IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject)
53
54 wxVariant WXDLLIMPEXP_BASE wxNullVariant;
55
56
57 /*
58 * wxVariant
59 */
60
61 IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
62
63 wxVariant::wxVariant()
64 {
65 m_data = (wxVariantData*) NULL;
66 }
67
68 bool wxVariant::IsNull() const
69 {
70 return (m_data == (wxVariantData*) NULL);
71 }
72
73 void wxVariant::MakeNull()
74 {
75 UnRef();
76 }
77
78 void wxVariant::Clear()
79 {
80 m_name = wxEmptyString;
81 }
82
83 wxVariant::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
94 wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
95 {
96 m_data = data;
97 m_name = name;
98 }
99
100 wxVariant::~wxVariant()
101 {
102 UnRef();
103 }
104
105 // Assignment
106 void wxVariant::operator= (const wxVariant& variant)
107 {
108 Ref(variant);
109 m_name = variant.m_name;
110 }
111
112 // myVariant = new wxStringVariantData("hello")
113 void wxVariant::operator= (wxVariantData* variantData)
114 {
115 UnRef();
116 m_data = variantData;
117 }
118
119 bool 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
127 bool wxVariant::operator!= (const wxVariant& variant) const
128 {
129 return (!(*this == variant));
130 }
131
132
133 wxString wxVariant::MakeString() const
134 {
135 if (!IsNull())
136 {
137 wxString str;
138 if (GetData()->Write(str))
139 return str;
140 }
141 return wxEmptyString;
142 }
143
144 void wxVariant::SetData(wxVariantData* data)
145 {
146 UnRef();
147 m_data = data;
148 }
149
150 void wxVariant::Ref(const wxVariant& clone)
151 {
152 // nothing to be done
153 if (m_data == clone.m_data)
154 return;
155
156 // delete reference to old data
157 UnRef();
158
159 // reference new data
160 if ( clone.m_data )
161 {
162 m_data = clone.m_data;
163 m_data->m_count++;
164 }
165 }
166
167
168 void wxVariant::UnRef()
169 {
170 if ( m_data )
171 {
172 wxASSERT_MSG( m_data->m_count > 0, _T("invalid ref data count") );
173
174 m_data->DecRef();
175 m_data = NULL;
176 }
177 }
178
179
180 // Returns a string representing the type of the variant,
181 // e.g. "string", "bool", "list", "double", "long"
182 wxString wxVariant::GetType() const
183 {
184 if (IsNull())
185 return wxString(wxT("null"));
186 else
187 return GetData()->GetType();
188 }
189
190
191 bool wxVariant::IsType(const wxString& type) const
192 {
193 return (GetType() == type);
194 }
195
196 bool 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
207 class WXDLLIMPEXP_BASE wxVariantDataLong: public wxVariantData
208 {
209 DECLARE_DYNAMIC_CLASS(wxVariantDataLong)
210 public:
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
232 protected:
233 long m_value;
234 };
235
236 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataLong, wxVariantData)
237
238 bool 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
248 bool 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
257 bool wxVariantDataLong::Write(wxString& str) const
258 {
259 str.Printf(wxT("%ld"), m_value);
260 return true;
261 }
262
263 #if wxUSE_STD_IOSTREAM
264 bool wxVariantDataLong::Read(wxSTD istream& str)
265 {
266 str >> m_value;
267 return true;
268 }
269 #endif
270
271 #if wxUSE_STREAMS
272 bool wxVariantDataLong::Write(wxOutputStream& str) const
273 {
274 wxTextOutputStream s(str);
275
276 s.Write32((size_t)m_value);
277 return true;
278 }
279
280 bool wxVariantDataLong::Read(wxInputStream& str)
281 {
282 wxTextInputStream s(str);
283 m_value = s.Read32();
284 return true;
285 }
286 #endif // wxUSE_STREAMS
287
288 bool wxVariantDataLong::Read(wxString& str)
289 {
290 m_value = wxAtol(str);
291 return true;
292 }
293
294 // wxVariant
295
296 wxVariant::wxVariant(long val, const wxString& name)
297 {
298 m_data = new wxVariantDataLong(val);
299 m_name = name;
300 }
301
302 wxVariant::wxVariant(int val, const wxString& name)
303 {
304 m_data = new wxVariantDataLong((long)val);
305 m_name = name;
306 }
307
308 wxVariant::wxVariant(short val, const wxString& name)
309 {
310 m_data = new wxVariantDataLong((long)val);
311 m_name = name;
312 }
313
314 bool wxVariant::operator== (long value) const
315 {
316 long thisValue;
317 if (!Convert(&thisValue))
318 return false;
319 else
320 return (value == thisValue);
321 }
322
323 bool wxVariant::operator!= (long value) const
324 {
325 return (!((*this) == value));
326 }
327
328 void 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
342 long 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
358 class WXDLLIMPEXP_BASE wxVariantDoubleData: public wxVariantData
359 {
360 DECLARE_DYNAMIC_CLASS(wxVariantDoubleData)
361 public:
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
383 protected:
384 double m_value;
385 };
386
387 IMPLEMENT_DYNAMIC_CLASS(wxVariantDoubleData, wxVariantData)
388
389 bool 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
399 bool 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
408 bool wxVariantDoubleData::Write(wxString& str) const
409 {
410 str.Printf(wxT("%.14g"), m_value);
411 return true;
412 }
413
414 #if wxUSE_STD_IOSTREAM
415 bool wxVariantDoubleData::Read(wxSTD istream& str)
416 {
417 str >> m_value;
418 return true;
419 }
420 #endif
421
422 #if wxUSE_STREAMS
423 bool wxVariantDoubleData::Write(wxOutputStream& str) const
424 {
425 wxTextOutputStream s(str);
426 s.WriteDouble((double)m_value);
427 return true;
428 }
429
430 bool wxVariantDoubleData::Read(wxInputStream& str)
431 {
432 wxTextInputStream s(str);
433 m_value = (float)s.ReadDouble();
434 return true;
435 }
436 #endif // wxUSE_STREAMS
437
438 bool wxVariantDoubleData::Read(wxString& str)
439 {
440 m_value = wxAtof(str);
441 return true;
442 }
443
444 // wxVariant double code
445
446 wxVariant::wxVariant(double val, const wxString& name)
447 {
448 m_data = new wxVariantDoubleData(val);
449 m_name = name;
450 }
451
452 bool wxVariant::operator== (double value) const
453 {
454 double thisValue;
455 if (!Convert(&thisValue))
456 return false;
457
458 return wxIsSameDouble(value, thisValue);
459 }
460
461 bool wxVariant::operator!= (double value) const
462 {
463 return (!((*this) == value));
464 }
465
466 void 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
480 double 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
498 class WXDLLIMPEXP_BASE wxVariantDataBool: public wxVariantData
499 {
500 DECLARE_DYNAMIC_CLASS(wxVariantDataBool)
501 public:
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
523 protected:
524 bool m_value;
525 };
526
527 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataBool, wxVariantData)
528
529 bool 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
539 bool 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
548 bool wxVariantDataBool::Write(wxString& str) const
549 {
550 str.Printf(wxT("%d"), (int) m_value);
551 return true;
552 }
553
554 #if wxUSE_STD_IOSTREAM
555 bool 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
564 bool wxVariantDataBool::Write(wxOutputStream& str) const
565 {
566 wxTextOutputStream s(str);
567
568 s.Write8(m_value);
569 return true;
570 }
571
572 bool 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
581 bool wxVariantDataBool::Read(wxString& str)
582 {
583 m_value = (wxAtol(str) != 0);
584 return true;
585 }
586
587 // wxVariant ****
588
589 wxVariant::wxVariant(bool val, const wxString& name)
590 {
591 m_data = new wxVariantDataBool(val);
592 m_name = name;
593 }
594
595 bool wxVariant::operator== (bool value) const
596 {
597 bool thisValue;
598 if (!Convert(&thisValue))
599 return false;
600 else
601 return (value == thisValue);
602 }
603
604 bool wxVariant::operator!= (bool value) const
605 {
606 return (!((*this) == value));
607 }
608
609 void 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
623 bool 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
641 class WXDLLIMPEXP_BASE wxVariantDataChar: public wxVariantData
642 {
643 DECLARE_DYNAMIC_CLASS(wxVariantDataChar)
644 public:
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
664 protected:
665 wxUniChar m_value;
666 };
667
668 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataChar, wxVariantData)
669
670 bool 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
680 bool wxVariantDataChar::Write(wxSTD ostream& str) const
681 {
682 str << wxString(m_value);
683 return true;
684 }
685 #endif
686
687 bool wxVariantDataChar::Write(wxString& str) const
688 {
689 str = m_value;
690 return true;
691 }
692
693 #if wxUSE_STD_IOSTREAM
694 bool wxVariantDataChar::Read(wxSTD istream& WXUNUSED(str))
695 {
696 wxFAIL_MSG(wxT("Unimplemented"));
697
698 return false;
699 }
700 #endif
701
702 #if wxUSE_STREAMS
703 bool 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
714 bool 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
728 bool wxVariantDataChar::Read(wxString& str)
729 {
730 m_value = str[0u];
731 return true;
732 }
733
734 wxVariant::wxVariant(const wxUniChar& val, const wxString& name)
735 {
736 m_data = new wxVariantDataChar(val);
737 m_name = name;
738 }
739
740 wxVariant::wxVariant(char val, const wxString& name)
741 {
742 m_data = new wxVariantDataChar(val);
743 m_name = name;
744 }
745
746 wxVariant::wxVariant(wchar_t val, const wxString& name)
747 {
748 m_data = new wxVariantDataChar(val);
749 m_name = name;
750 }
751
752 bool 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
761 wxVariant& 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
777 wxUniChar 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
793 class WXDLLIMPEXP_BASE wxVariantDataString: public wxVariantData
794 {
795 DECLARE_DYNAMIC_CLASS(wxVariantDataString)
796 public:
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
818 protected:
819 wxString m_value;
820 };
821
822 bool 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
832 bool wxVariantDataString::Write(wxSTD ostream& str) const
833 {
834 str << (const char*) m_value.mb_str();
835 return true;
836 }
837 #endif
838
839 bool wxVariantDataString::Write(wxString& str) const
840 {
841 str = m_value;
842 return true;
843 }
844
845 #if wxUSE_STREAMS
846 bool 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
854 bool wxVariantDataString::Read(wxInputStream& str)
855 {
856 wxTextInputStream s(str);
857
858 m_value = s.ReadLine();
859 return true;
860 }
861 #endif // wxUSE_STREAMS
862
863 bool wxVariantDataString::Read(wxString& str)
864 {
865 m_value = str;
866 return true;
867 }
868
869 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
870
871 // wxVariant ****
872
873 wxVariant::wxVariant(const wxString& val, const wxString& name)
874 {
875 m_data = new wxVariantDataString(val);
876 m_name = name;
877 }
878
879 wxVariant::wxVariant(const char* val, const wxString& name)
880 {
881 m_data = new wxVariantDataString(wxString(val));
882 m_name = name;
883 }
884
885 wxVariant::wxVariant(const wchar_t* val, const wxString& name)
886 {
887 m_data = new wxVariantDataString(wxString(val));
888 m_name = name;
889 }
890
891 wxVariant::wxVariant(const wxCStrData& val, const wxString& name)
892 {
893 m_data = new wxVariantDataString(val.AsString());
894 m_name = name;
895 }
896
897 wxVariant::wxVariant(const wxCharBuffer& val, const wxString& name)
898 {
899 m_data = new wxVariantDataString(wxString(val));
900 m_name = name;
901 }
902
903 wxVariant::wxVariant(const wxWCharBuffer& val, const wxString& name)
904 {
905 m_data = new wxVariantDataString(wxString(val));
906 m_name = name;
907 }
908
909 bool wxVariant::operator== (const wxString& value) const
910 {
911 wxString thisValue;
912 if (!Convert(&thisValue))
913 return false;
914
915 return value == thisValue;
916 }
917
918 bool wxVariant::operator!= (const wxString& value) const
919 {
920 return (!((*this) == value));
921 }
922
923 wxVariant& 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
938 wxString 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
953 class wxVariantDataWxObjectPtr: public wxVariantData
954 {
955 DECLARE_DYNAMIC_CLASS(wxVariantDataWxObjectPtr)
956 public:
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() ;
976 protected:
977 wxObject* m_value;
978
979 DECLARE_NO_COPY_CLASS(wxVariantDataWxObjectPtr)
980 };
981
982 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataWxObjectPtr, wxVariantData)
983
984 bool 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
993 wxString 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
1002 wxClassInfo* 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
1012 bool 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
1021 bool 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
1028 bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
1029 {
1030 // Not implemented
1031 return false;
1032 }
1033 #endif
1034
1035 bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
1036 {
1037 // Not implemented
1038 return false;
1039 }
1040
1041 // wxVariant
1042
1043 wxVariant::wxVariant( wxObject* val, const wxString& name)
1044 {
1045 m_data = new wxVariantDataWxObjectPtr(val);
1046 m_name = name;
1047 }
1048
1049 bool wxVariant::operator== (wxObject* value) const
1050 {
1051 return (value == ((wxVariantDataWxObjectPtr*)GetData())->GetValue());
1052 }
1053
1054 bool wxVariant::operator!= (wxObject* value) const
1055 {
1056 return (!((*this) == (wxObject*) value));
1057 }
1058
1059 void wxVariant::operator= (wxObject* value)
1060 {
1061 UnRef();
1062 m_data = new wxVariantDataWxObjectPtr(value);
1063 }
1064
1065 wxObject* wxVariant::GetWxObjectPtr() const
1066 {
1067 wxASSERT(wxIsKindOf(GetData(), wxVariantDataWxObjectPtr));
1068 return (wxObject*) ((wxVariantDataWxObjectPtr*) m_data)->GetValue();
1069 }
1070
1071 // ----------------------------------------------------------------------------
1072 // wxVariantDataVoidPtr
1073 // ----------------------------------------------------------------------------
1074
1075 class wxVariantDataVoidPtr: public wxVariantData
1076 {
1077 DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
1078 public:
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
1097 protected:
1098 void* m_value;
1099
1100 DECLARE_NO_COPY_CLASS(wxVariantDataVoidPtr)
1101 };
1102
1103 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
1104
1105 bool 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
1115 bool 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
1124 bool wxVariantDataVoidPtr::Write(wxString& str) const
1125 {
1126 str.Printf(wxT("%p"), m_value);
1127 return true;
1128 }
1129
1130 #if wxUSE_STD_IOSTREAM
1131 bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
1132 {
1133 // Not implemented
1134 return false;
1135 }
1136 #endif
1137
1138 bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
1139 {
1140 // Not implemented
1141 return false;
1142 }
1143
1144 // wxVariant
1145
1146 wxVariant::wxVariant( void* val, const wxString& name)
1147 {
1148 m_data = new wxVariantDataVoidPtr(val);
1149 m_name = name;
1150 }
1151
1152 bool wxVariant::operator== (void* value) const
1153 {
1154 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
1155 }
1156
1157 bool wxVariant::operator!= (void* value) const
1158 {
1159 return (!((*this) == (void*) value));
1160 }
1161
1162 void 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
1176 void* 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
1189 class wxVariantDataDateTime: public wxVariantData
1190 {
1191 DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime)
1192
1193 public:
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
1221 protected:
1222 wxDateTime m_value;
1223 };
1224
1225
1226 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime, wxVariantData)
1227
1228 bool 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
1239 bool 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
1249 bool wxVariantDataDateTime::Write(wxString& str) const
1250 {
1251 str = m_value.Format();
1252 return true;
1253 }
1254
1255
1256 #if wxUSE_STD_IOSTREAM
1257 bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
1258 {
1259 // Not implemented
1260 return false;
1261 }
1262 #endif
1263
1264
1265 bool 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
1274 wxVariant::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
1281 wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1282 {
1283 m_data = new wxVariantDataDateTime(valptr);
1284 m_name = name;
1285 }
1286
1287 wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1288 {
1289 m_data = new wxVariantDataDateTime(valptr);
1290 m_name = name;
1291 }
1292
1293 wxVariant::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
1300 bool 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
1309 bool wxVariant::operator!= (const wxDateTime& value) const
1310 {
1311 return (!((*this) == value));
1312 }
1313
1314 void 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
1329 void wxVariant::operator= (const DATE_STRUCT* value)
1330 {
1331 UnRef();
1332 m_data = new wxVariantDataDateTime(value);
1333 }
1334
1335 void wxVariant::operator= (const TIME_STRUCT* value)
1336 {
1337 UnRef();
1338 m_data = new wxVariantDataDateTime(value);
1339 }
1340
1341 void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
1342 {
1343 UnRef();
1344 m_data = new wxVariantDataDateTime(value);
1345 }
1346
1347 #endif // wxUSE_ODBC
1348
1349 wxDateTime 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
1366 class wxVariantDataArrayString: public wxVariantData
1367 {
1368 public:
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
1387 protected:
1388 wxArrayString m_value;
1389
1390 DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString)
1391 };
1392
1393 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString, wxVariantData)
1394
1395 bool 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
1405 bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
1406 {
1407 // Not implemented
1408 return false;
1409 }
1410 #endif
1411
1412 bool 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
1428 bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
1429 {
1430 // Not implemented
1431 return false;
1432 }
1433 #endif
1434
1435
1436 bool 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
1449 wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1450 {
1451 m_data = new wxVariantDataArrayString(val);
1452 m_name = name;
1453 }
1454
1455 bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
1456 {
1457 wxFAIL_MSG( _T("TODO") );
1458
1459 return false;
1460 }
1461
1462 bool wxVariant::operator!=(const wxArrayString& value) const
1463 {
1464 return !(*this == value);
1465 }
1466
1467 void 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
1481 wxArrayString 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
1493 class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
1494 {
1495 DECLARE_DYNAMIC_CLASS(wxVariantDataList)
1496 public:
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
1517 protected:
1518 wxList m_value;
1519 };
1520
1521 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
1522
1523 wxVariantDataList::wxVariantDataList(const wxList& list)
1524 {
1525 SetValue(list);
1526 }
1527
1528 wxVariantDataList::~wxVariantDataList()
1529 {
1530 Clear();
1531 }
1532
1533 void 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
1545 void 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
1557 bool 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
1578 bool 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
1587 bool 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
1605 bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
1606 {
1607 wxFAIL_MSG(wxT("Unimplemented"));
1608 // TODO
1609 return false;
1610 }
1611 #endif
1612
1613 bool wxVariantDataList::Read(wxString& WXUNUSED(str))
1614 {
1615 wxFAIL_MSG(wxT("Unimplemented"));
1616 // TODO
1617 return false;
1618 }
1619
1620 // wxVariant
1621
1622 wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
1623 {
1624 m_data = new wxVariantDataList(val);
1625 m_name = name;
1626 }
1627
1628 bool 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
1636 bool wxVariant::operator!= (const wxList& value) const
1637 {
1638 return (!((*this) == value));
1639 }
1640
1641 void 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
1655 wxList& wxVariant::GetList() const
1656 {
1657 wxASSERT( (GetType() == wxT("list")) );
1658
1659 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1660 }
1661
1662 // Make empty list
1663 void wxVariant::NullList()
1664 {
1665 SetData(new wxVariantDataList());
1666 }
1667
1668 // Append to list
1669 void 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
1677 void 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
1685 bool 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
1701 bool 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
1714 void 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
1730 wxVariant 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
1743 wxVariant& 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
1757 size_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
1773 bool 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
1792 bool 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
1820 bool 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
1839 bool 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
1856 bool wxVariant::Convert(char* value) const
1857 {
1858 wxUniChar ch;
1859 if ( !Convert(&ch) )
1860 return false;
1861 *value = ch;
1862 return true;
1863 }
1864
1865 bool 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
1874 bool wxVariant::Convert(wxString* value) const
1875 {
1876 *value = MakeString();
1877 return true;
1878 }
1879
1880 #if wxUSE_DATETIME
1881 bool 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