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