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