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