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