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