1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/variant.cpp
3 // Purpose: wxVariant class, container for any type
4 // Author: Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
19 #include "wx/variant.h"
24 #include "wx/string.h"
28 #include "wx/stream.h"
32 #if wxUSE_STD_IOSTREAM
40 #if defined(__MWERKS__) && __MSL__ >= 0x6000
46 #include "wx/txtstrm.h"
49 #include "wx/string.h"
50 #include "wx/tokenzr.h"
52 IMPLEMENT_ABSTRACT_CLASS(wxVariantData
, wxObject
)
54 wxVariant WXDLLIMPEXP_BASE wxNullVariant
;
61 IMPLEMENT_DYNAMIC_CLASS(wxVariant
, wxObject
)
63 wxVariant::wxVariant()
65 m_data
= (wxVariantData
*) NULL
;
68 bool wxVariant::IsNull() const
70 return (m_data
== (wxVariantData
*) NULL
);
73 void wxVariant::MakeNull()
78 void wxVariant::Clear()
80 m_name
= wxEmptyString
;
83 wxVariant::wxVariant(const wxVariant
& variant
)
86 m_data
= (wxVariantData
*) NULL
;
88 if (!variant
.IsNull())
91 m_name
= variant
.m_name
;
94 wxVariant::wxVariant(wxVariantData
* data
, const wxString
& name
) // User-defined data
100 wxVariant::~wxVariant()
106 void wxVariant::operator= (const wxVariant
& variant
)
109 m_name
= variant
.m_name
;
112 // myVariant = new wxStringVariantData("hello")
113 void wxVariant::operator= (wxVariantData
* variantData
)
116 m_data
= variantData
;
119 bool wxVariant::operator== (const wxVariant
& variant
) const
121 if (IsNull() || variant
.IsNull())
122 return (IsNull() == variant
.IsNull());
124 return (GetData()->Eq(* variant
.GetData()));
127 bool wxVariant::operator!= (const wxVariant
& variant
) const
129 return (!(*this == variant
));
133 wxString
wxVariant::MakeString() const
138 if (GetData()->Write(str
))
141 return wxEmptyString
;
144 void wxVariant::SetData(wxVariantData
* data
)
150 void wxVariant::Ref(const wxVariant
& clone
)
152 // nothing to be done
153 if (m_data
== clone
.m_data
)
156 // delete reference to old data
159 // reference new data
162 m_data
= clone
.m_data
;
168 void wxVariant::UnRef()
172 wxASSERT_MSG( m_data
->m_count
> 0, _T("invalid ref data count") );
180 // Returns a string representing the type of the variant,
181 // e.g. "string", "bool", "list", "double", "long"
182 wxString
wxVariant::GetType() const
185 return wxString(wxT("null"));
187 return GetData()->GetType();
191 bool wxVariant::IsType(const wxString
& type
) const
193 return (GetType() == type
);
196 bool wxVariant::IsValueKindOf(const wxClassInfo
* type
) const
198 wxClassInfo
* info
=GetData()->GetValueClassInfo();
199 return info
? info
->IsKindOf(type
) : false ;
203 // -----------------------------------------------------------------
205 // -----------------------------------------------------------------
207 class WXDLLIMPEXP_BASE wxVariantDataLong
: public wxVariantData
209 DECLARE_DYNAMIC_CLASS(wxVariantDataLong
)
211 wxVariantDataLong() { m_value
= 0; }
212 wxVariantDataLong(long value
) { m_value
= value
; }
214 inline long GetValue() const { return m_value
; }
215 inline void SetValue(long value
) { m_value
= value
; }
217 virtual bool Eq(wxVariantData
& data
) const;
219 virtual bool Read(wxString
& str
);
220 virtual bool Write(wxString
& str
) const;
221 #if wxUSE_STD_IOSTREAM
222 virtual bool Read(wxSTD istream
& str
);
223 virtual bool Write(wxSTD ostream
& str
) const;
226 virtual bool Read(wxInputStream
& str
);
227 virtual bool Write(wxOutputStream
&str
) const;
228 #endif // wxUSE_STREAMS
230 virtual wxString
GetType() const { return wxT("long"); }
236 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataLong
, wxVariantData
)
238 bool wxVariantDataLong::Eq(wxVariantData
& data
) const
240 wxASSERT_MSG( (data
.GetType() == wxT("long")), wxT("wxVariantDataLong::Eq: argument mismatch") );
242 wxVariantDataLong
& otherData
= (wxVariantDataLong
&) data
;
244 return (otherData
.m_value
== m_value
);
247 #if wxUSE_STD_IOSTREAM
248 bool wxVariantDataLong::Write(wxSTD ostream
& str
) const
252 str
<< (const char*) s
.mb_str();
257 bool wxVariantDataLong::Write(wxString
& str
) const
259 str
.Printf(wxT("%ld"), m_value
);
263 #if wxUSE_STD_IOSTREAM
264 bool wxVariantDataLong::Read(wxSTD istream
& str
)
272 bool wxVariantDataLong::Write(wxOutputStream
& str
) const
274 wxTextOutputStream
s(str
);
276 s
.Write32((size_t)m_value
);
280 bool wxVariantDataLong::Read(wxInputStream
& str
)
282 wxTextInputStream
s(str
);
283 m_value
= s
.Read32();
286 #endif // wxUSE_STREAMS
288 bool wxVariantDataLong::Read(wxString
& str
)
290 m_value
= wxAtol(str
);
296 wxVariant::wxVariant(long val
, const wxString
& name
)
298 m_data
= new wxVariantDataLong(val
);
302 wxVariant::wxVariant(int val
, const wxString
& name
)
304 m_data
= new wxVariantDataLong((long)val
);
308 wxVariant::wxVariant(short val
, const wxString
& name
)
310 m_data
= new wxVariantDataLong((long)val
);
314 bool wxVariant::operator== (long value
) const
317 if (!Convert(&thisValue
))
320 return (value
== thisValue
);
323 bool wxVariant::operator!= (long value
) const
325 return (!((*this) == value
));
328 void wxVariant::operator= (long value
)
330 if (GetType() == wxT("long") &&
331 m_data
->GetRefCount() == 1)
333 ((wxVariantDataLong
*)GetData())->SetValue(value
);
338 m_data
= new wxVariantDataLong(value
);
342 long wxVariant::GetLong() const
345 if (Convert(& value
))
349 wxFAIL_MSG(wxT("Could not convert to a long"));
354 // -----------------------------------------------------------------
355 // wxVariantDoubleData
356 // -----------------------------------------------------------------
358 class WXDLLIMPEXP_BASE wxVariantDoubleData
: public wxVariantData
360 DECLARE_DYNAMIC_CLASS(wxVariantDoubleData
)
362 wxVariantDoubleData() { m_value
= 0.0; }
363 wxVariantDoubleData(double value
) { m_value
= value
; }
365 inline double GetValue() const { return m_value
; }
366 inline void SetValue(double value
) { m_value
= value
; }
368 virtual bool Eq(wxVariantData
& data
) const;
369 virtual bool Read(wxString
& str
);
370 #if wxUSE_STD_IOSTREAM
371 virtual bool Write(wxSTD ostream
& str
) const;
373 virtual bool Write(wxString
& str
) const;
374 #if wxUSE_STD_IOSTREAM
375 virtual bool Read(wxSTD istream
& str
);
378 virtual bool Read(wxInputStream
& str
);
379 virtual bool Write(wxOutputStream
&str
) const;
380 #endif // wxUSE_STREAMS
381 virtual wxString
GetType() const { return wxT("double"); }
387 IMPLEMENT_DYNAMIC_CLASS(wxVariantDoubleData
, wxVariantData
)
389 bool wxVariantDoubleData::Eq(wxVariantData
& data
) const
391 wxASSERT_MSG( (data
.GetType() == wxT("double")), wxT("wxVariantDoubleData::Eq: argument mismatch") );
393 wxVariantDoubleData
& otherData
= (wxVariantDoubleData
&) data
;
395 return wxIsSameDouble(otherData
.m_value
, m_value
);
398 #if wxUSE_STD_IOSTREAM
399 bool wxVariantDoubleData::Write(wxSTD ostream
& str
) const
403 str
<< (const char*) s
.mb_str();
408 bool wxVariantDoubleData::Write(wxString
& str
) const
410 str
.Printf(wxT("%.14g"), m_value
);
414 #if wxUSE_STD_IOSTREAM
415 bool wxVariantDoubleData::Read(wxSTD istream
& str
)
423 bool wxVariantDoubleData::Write(wxOutputStream
& str
) const
425 wxTextOutputStream
s(str
);
426 s
.WriteDouble((double)m_value
);
430 bool wxVariantDoubleData::Read(wxInputStream
& str
)
432 wxTextInputStream
s(str
);
433 m_value
= (float)s
.ReadDouble();
436 #endif // wxUSE_STREAMS
438 bool wxVariantDoubleData::Read(wxString
& str
)
440 m_value
= wxAtof(str
);
444 // wxVariant double code
446 wxVariant::wxVariant(double val
, const wxString
& name
)
448 m_data
= new wxVariantDoubleData(val
);
452 bool wxVariant::operator== (double value
) const
455 if (!Convert(&thisValue
))
458 return wxIsSameDouble(value
, thisValue
);
461 bool wxVariant::operator!= (double value
) const
463 return (!((*this) == value
));
466 void wxVariant::operator= (double value
)
468 if (GetType() == wxT("double") &&
469 m_data
->GetRefCount() == 1)
471 ((wxVariantDoubleData
*)GetData())->SetValue(value
);
476 m_data
= new wxVariantDoubleData(value
);
480 double wxVariant::GetDouble() const
483 if (Convert(& value
))
487 wxFAIL_MSG(wxT("Could not convert to a double number"));
492 // -----------------------------------------------------------------
494 // -----------------------------------------------------------------
498 class WXDLLIMPEXP_BASE wxVariantDataBool
: public wxVariantData
500 DECLARE_DYNAMIC_CLASS(wxVariantDataBool
)
502 wxVariantDataBool() { m_value
= 0; }
503 wxVariantDataBool(bool value
) { m_value
= value
; }
505 inline bool GetValue() const { return m_value
; }
506 inline void SetValue(bool value
) { m_value
= value
; }
508 virtual bool Eq(wxVariantData
& data
) const;
509 #if wxUSE_STD_IOSTREAM
510 virtual bool Write(wxSTD ostream
& str
) const;
512 virtual bool Write(wxString
& str
) const;
513 virtual bool Read(wxString
& str
);
514 #if wxUSE_STD_IOSTREAM
515 virtual bool Read(wxSTD istream
& str
);
518 virtual bool Read(wxInputStream
& str
);
519 virtual bool Write(wxOutputStream
& str
) const;
520 #endif // wxUSE_STREAMS
521 virtual wxString
GetType() const { return wxT("bool"); }
527 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataBool
, wxVariantData
)
529 bool wxVariantDataBool::Eq(wxVariantData
& data
) const
531 wxASSERT_MSG( (data
.GetType() == wxT("bool")), wxT("wxVariantDataBool::Eq: argument mismatch") );
533 wxVariantDataBool
& otherData
= (wxVariantDataBool
&) data
;
535 return (otherData
.m_value
== m_value
);
538 #if wxUSE_STD_IOSTREAM
539 bool wxVariantDataBool::Write(wxSTD ostream
& str
) const
543 str
<< (const char*) s
.mb_str();
548 bool wxVariantDataBool::Write(wxString
& str
) const
550 str
.Printf(wxT("%d"), (int) m_value
);
554 #if wxUSE_STD_IOSTREAM
555 bool wxVariantDataBool::Read(wxSTD istream
& WXUNUSED(str
))
557 wxFAIL_MSG(wxT("Unimplemented"));
558 // str >> (long) m_value;
564 bool wxVariantDataBool::Write(wxOutputStream
& str
) const
566 wxTextOutputStream
s(str
);
572 bool wxVariantDataBool::Read(wxInputStream
& str
)
574 wxTextInputStream
s(str
);
576 m_value
= s
.Read8() != 0;
579 #endif // wxUSE_STREAMS
581 bool wxVariantDataBool::Read(wxString
& str
)
583 m_value
= (wxAtol(str
) != 0);
589 wxVariant::wxVariant(bool val
, const wxString
& name
)
591 m_data
= new wxVariantDataBool(val
);
595 bool wxVariant::operator== (bool value
) const
598 if (!Convert(&thisValue
))
601 return (value
== thisValue
);
604 bool wxVariant::operator!= (bool value
) const
606 return (!((*this) == value
));
609 void wxVariant::operator= (bool value
)
611 if (GetType() == wxT("bool") &&
612 m_data
->GetRefCount() == 1)
614 ((wxVariantDataBool
*)GetData())->SetValue(value
);
619 m_data
= new wxVariantDataBool(value
);
623 bool wxVariant::GetBool() const
626 if (Convert(& value
))
630 wxFAIL_MSG(wxT("Could not convert to a bool"));
637 // -----------------------------------------------------------------
639 // -----------------------------------------------------------------
641 class WXDLLIMPEXP_BASE wxVariantDataChar
: public wxVariantData
643 DECLARE_DYNAMIC_CLASS(wxVariantDataChar
)
645 wxVariantDataChar() { m_value
= 0; }
646 wxVariantDataChar(const wxUniChar
& value
) { m_value
= value
; }
648 inline wxUniChar
GetValue() const { return m_value
; }
649 inline void SetValue(const wxUniChar
& value
) { m_value
= value
; }
651 virtual bool Eq(wxVariantData
& data
) const;
652 #if wxUSE_STD_IOSTREAM
653 virtual bool Read(wxSTD istream
& str
);
654 virtual bool Write(wxSTD ostream
& str
) const;
656 virtual bool Read(wxString
& str
);
657 virtual bool Write(wxString
& str
) const;
659 virtual bool Read(wxInputStream
& str
);
660 virtual bool Write(wxOutputStream
& str
) const;
661 #endif // wxUSE_STREAMS
662 virtual wxString
GetType() const { return wxT("char"); }
668 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataChar
, wxVariantData
)
670 bool wxVariantDataChar::Eq(wxVariantData
& data
) const
672 wxASSERT_MSG( (data
.GetType() == wxT("char")), wxT("wxVariantDataChar::Eq: argument mismatch") );
674 wxVariantDataChar
& otherData
= (wxVariantDataChar
&) data
;
676 return (otherData
.m_value
== m_value
);
679 #if wxUSE_STD_IOSTREAM
680 bool wxVariantDataChar::Write(wxSTD ostream
& str
) const
682 str
<< wxString(m_value
);
687 bool wxVariantDataChar::Write(wxString
& str
) const
693 #if wxUSE_STD_IOSTREAM
694 bool wxVariantDataChar::Read(wxSTD istream
& WXUNUSED(str
))
696 wxFAIL_MSG(wxT("Unimplemented"));
703 bool wxVariantDataChar::Write(wxOutputStream
& str
) const
705 wxTextOutputStream
s(str
);
707 // FIXME-UTF8: this should be just "s << m_value;" after removal of
708 // ANSI build and addition of wxUniChar to wxTextOutputStream:
709 s
<< (wxChar
)m_value
;
714 bool wxVariantDataChar::Read(wxInputStream
& str
)
716 wxTextInputStream
s(str
);
718 // FIXME-UTF8: this should be just "s >> m_value;" after removal of
719 // ANSI build and addition of wxUniChar to wxTextInputStream:
726 #endif // wxUSE_STREAMS
728 bool wxVariantDataChar::Read(wxString
& str
)
734 wxVariant::wxVariant(const wxUniChar
& val
, const wxString
& name
)
736 m_data
= new wxVariantDataChar(val
);
740 wxVariant::wxVariant(char val
, const wxString
& name
)
742 m_data
= new wxVariantDataChar(val
);
746 wxVariant::wxVariant(wchar_t val
, const wxString
& name
)
748 m_data
= new wxVariantDataChar(val
);
752 bool wxVariant::operator==(const wxUniChar
& value
) const
755 if (!Convert(&thisValue
))
758 return (value
== thisValue
);
761 wxVariant
& wxVariant::operator=(const wxUniChar
& value
)
763 if (GetType() == wxT("char") &&
764 m_data
->GetRefCount() == 1)
766 ((wxVariantDataChar
*)GetData())->SetValue(value
);
771 m_data
= new wxVariantDataChar(value
);
777 wxUniChar
wxVariant::GetChar() const
780 if (Convert(& value
))
784 wxFAIL_MSG(wxT("Could not convert to a char"));
789 // ----------------------------------------------------------------------------
790 // wxVariantDataString
791 // ----------------------------------------------------------------------------
793 class WXDLLIMPEXP_BASE wxVariantDataString
: public wxVariantData
795 DECLARE_DYNAMIC_CLASS(wxVariantDataString
)
797 wxVariantDataString() { }
798 wxVariantDataString(const wxString
& value
) { m_value
= value
; }
800 inline wxString
GetValue() const { return m_value
; }
801 inline void SetValue(const wxString
& value
) { m_value
= value
; }
803 virtual bool Eq(wxVariantData
& data
) const;
804 #if wxUSE_STD_IOSTREAM
805 virtual bool Write(wxSTD ostream
& str
) const;
807 virtual bool Read(wxString
& str
);
808 virtual bool Write(wxString
& str
) const;
809 #if wxUSE_STD_IOSTREAM
810 virtual bool Read(wxSTD istream
& WXUNUSED(str
)) { return false; }
813 virtual bool Read(wxInputStream
& str
);
814 virtual bool Write(wxOutputStream
& str
) const;
815 #endif // wxUSE_STREAMS
816 virtual wxString
GetType() const { return wxT("string"); }
822 bool wxVariantDataString::Eq(wxVariantData
& data
) const
824 wxASSERT_MSG( (data
.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
826 wxVariantDataString
& otherData
= (wxVariantDataString
&) data
;
828 return (otherData
.m_value
== m_value
);
831 #if wxUSE_STD_IOSTREAM
832 bool wxVariantDataString::Write(wxSTD ostream
& str
) const
834 str
<< (const char*) m_value
.mb_str();
839 bool wxVariantDataString::Write(wxString
& str
) const
846 bool wxVariantDataString::Write(wxOutputStream
& str
) const
848 // why doesn't wxOutputStream::operator<< take "const wxString&"
849 wxTextOutputStream
s(str
);
850 s
.WriteString(m_value
);
854 bool wxVariantDataString::Read(wxInputStream
& str
)
856 wxTextInputStream
s(str
);
858 m_value
= s
.ReadLine();
861 #endif // wxUSE_STREAMS
863 bool wxVariantDataString::Read(wxString
& str
)
869 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString
, wxVariantData
)
873 wxVariant::wxVariant(const wxString
& val
, const wxString
& name
)
875 m_data
= new wxVariantDataString(val
);
879 wxVariant::wxVariant(const char* val
, const wxString
& name
)
881 m_data
= new wxVariantDataString(wxString(val
));
885 wxVariant::wxVariant(const wchar_t* val
, const wxString
& name
)
887 m_data
= new wxVariantDataString(wxString(val
));
891 wxVariant::wxVariant(const wxCStrData
& val
, const wxString
& name
)
893 m_data
= new wxVariantDataString(val
.AsString());
897 wxVariant::wxVariant(const wxCharBuffer
& val
, const wxString
& name
)
899 m_data
= new wxVariantDataString(wxString(val
));
903 wxVariant::wxVariant(const wxWCharBuffer
& val
, const wxString
& name
)
905 m_data
= new wxVariantDataString(wxString(val
));
909 bool wxVariant::operator== (const wxString
& value
) const
912 if (!Convert(&thisValue
))
915 return value
== thisValue
;
918 bool wxVariant::operator!= (const wxString
& value
) const
920 return (!((*this) == value
));
923 wxVariant
& wxVariant::operator= (const wxString
& value
)
925 if (GetType() == wxT("string") &&
926 m_data
->GetRefCount() == 1)
928 ((wxVariantDataString
*)GetData())->SetValue(value
);
933 m_data
= new wxVariantDataString(value
);
938 wxString
wxVariant::GetString() const
941 if (!Convert(& value
))
943 wxFAIL_MSG(wxT("Could not convert to a string"));
949 // ----------------------------------------------------------------------------
950 // wxVariantDataWxObjectPtr
951 // ----------------------------------------------------------------------------
953 class wxVariantDataWxObjectPtr
: public wxVariantData
955 DECLARE_DYNAMIC_CLASS(wxVariantDataWxObjectPtr
)
957 wxVariantDataWxObjectPtr() { }
958 wxVariantDataWxObjectPtr(wxObject
* value
) { m_value
= value
; }
960 inline wxObject
* GetValue() const { return m_value
; }
961 inline void SetValue(wxObject
* value
) { m_value
= value
; }
963 virtual bool Eq(wxVariantData
& data
) const;
964 #if wxUSE_STD_IOSTREAM
965 virtual bool Write(wxSTD ostream
& str
) const;
967 virtual bool Write(wxString
& str
) const;
968 #if wxUSE_STD_IOSTREAM
969 virtual bool Read(wxSTD istream
& str
);
971 virtual bool Read(wxString
& str
);
972 virtual wxString
GetType() const ;
973 virtual wxVariantData
* Clone() { return new wxVariantDataWxObjectPtr
; }
975 virtual wxClassInfo
* GetValueClassInfo() ;
979 DECLARE_NO_COPY_CLASS(wxVariantDataWxObjectPtr
)
982 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataWxObjectPtr
, wxVariantData
)
984 bool wxVariantDataWxObjectPtr::Eq(wxVariantData
& data
) const
986 wxASSERT_MSG( wxIsKindOf((&data
), wxVariantDataWxObjectPtr
), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
988 wxVariantDataWxObjectPtr
& otherData
= (wxVariantDataWxObjectPtr
&) data
;
990 return (otherData
.m_value
== m_value
);
993 wxString
wxVariantDataWxObjectPtr::GetType() const
995 wxString
returnVal(wxT("wxObject"));
997 returnVal
= m_value
->GetClassInfo()->GetClassName();
1002 wxClassInfo
* wxVariantDataWxObjectPtr::GetValueClassInfo()
1004 wxClassInfo
* returnVal
=NULL
;
1006 if (m_value
) returnVal
= m_value
->GetClassInfo();
1011 #if wxUSE_STD_IOSTREAM
1012 bool wxVariantDataWxObjectPtr::Write(wxSTD ostream
& str
) const
1016 str
<< (const char*) s
.mb_str();
1021 bool wxVariantDataWxObjectPtr::Write(wxString
& str
) const
1023 str
.Printf(wxT("%s(%p)"), GetType().c_str(), wx_static_cast(void*, m_value
));
1027 #if wxUSE_STD_IOSTREAM
1028 bool wxVariantDataWxObjectPtr::Read(wxSTD istream
& WXUNUSED(str
))
1035 bool wxVariantDataWxObjectPtr::Read(wxString
& WXUNUSED(str
))
1043 wxVariant::wxVariant( wxObject
* val
, const wxString
& name
)
1045 m_data
= new wxVariantDataWxObjectPtr(val
);
1049 bool wxVariant::operator== (wxObject
* value
) const
1051 return (value
== ((wxVariantDataWxObjectPtr
*)GetData())->GetValue());
1054 bool wxVariant::operator!= (wxObject
* value
) const
1056 return (!((*this) == (wxObject
*) value
));
1059 void wxVariant::operator= (wxObject
* value
)
1062 m_data
= new wxVariantDataWxObjectPtr(value
);
1065 wxObject
* wxVariant::GetWxObjectPtr() const
1067 wxASSERT(wxIsKindOf(GetData(), wxVariantDataWxObjectPtr
));
1068 return (wxObject
*) ((wxVariantDataWxObjectPtr
*) m_data
)->GetValue();
1071 // ----------------------------------------------------------------------------
1072 // wxVariantDataVoidPtr
1073 // ----------------------------------------------------------------------------
1075 class wxVariantDataVoidPtr
: public wxVariantData
1077 DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr
)
1079 wxVariantDataVoidPtr() { }
1080 wxVariantDataVoidPtr(void* value
) { m_value
= value
; }
1082 inline void* GetValue() const { return m_value
; }
1083 inline void SetValue(void* value
) { m_value
= value
; }
1085 virtual bool Eq(wxVariantData
& data
) const;
1086 #if wxUSE_STD_IOSTREAM
1087 virtual bool Write(wxSTD ostream
& str
) const;
1089 virtual bool Write(wxString
& str
) const;
1090 #if wxUSE_STD_IOSTREAM
1091 virtual bool Read(wxSTD istream
& str
);
1093 virtual bool Read(wxString
& str
);
1094 virtual wxString
GetType() const { return wxT("void*"); }
1095 virtual wxVariantData
* Clone() { return new wxVariantDataVoidPtr
; }
1100 DECLARE_NO_COPY_CLASS(wxVariantDataVoidPtr
)
1103 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr
, wxVariantData
)
1105 bool wxVariantDataVoidPtr::Eq(wxVariantData
& data
) const
1107 wxASSERT_MSG( (data
.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
1109 wxVariantDataVoidPtr
& otherData
= (wxVariantDataVoidPtr
&) data
;
1111 return (otherData
.m_value
== m_value
);
1114 #if wxUSE_STD_IOSTREAM
1115 bool wxVariantDataVoidPtr::Write(wxSTD ostream
& str
) const
1119 str
<< (const char*) s
.mb_str();
1124 bool wxVariantDataVoidPtr::Write(wxString
& str
) const
1126 str
.Printf(wxT("%p"), m_value
);
1130 #if wxUSE_STD_IOSTREAM
1131 bool wxVariantDataVoidPtr::Read(wxSTD istream
& WXUNUSED(str
))
1138 bool wxVariantDataVoidPtr::Read(wxString
& WXUNUSED(str
))
1146 wxVariant::wxVariant( void* val
, const wxString
& name
)
1148 m_data
= new wxVariantDataVoidPtr(val
);
1152 bool wxVariant::operator== (void* value
) const
1154 return (value
== ((wxVariantDataVoidPtr
*)GetData())->GetValue());
1157 bool wxVariant::operator!= (void* value
) const
1159 return (!((*this) == (void*) value
));
1162 void wxVariant::operator= (void* value
)
1164 if (GetType() == wxT("void*") &&
1165 m_data
->GetRefCount() == 1)
1167 ((wxVariantDataVoidPtr
*)GetData())->SetValue(value
);
1172 m_data
= new wxVariantDataVoidPtr(value
);
1176 void* wxVariant::GetVoidPtr() const
1178 wxASSERT( (GetType() == wxT("void*")) );
1180 return (void*) ((wxVariantDataVoidPtr
*) m_data
)->GetValue();
1183 // ----------------------------------------------------------------------------
1184 // wxVariantDataDateTime
1185 // ----------------------------------------------------------------------------
1189 class wxVariantDataDateTime
: public wxVariantData
1191 DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime
)
1194 wxVariantDataDateTime() { }
1195 wxVariantDataDateTime(const wxDateTime
& value
) { m_value
= value
; }
1197 wxVariantDataDateTime(const TIME_STRUCT
* valptr
)
1198 { m_value
= wxDateTime(valptr
->hour
, valptr
->minute
, valptr
->second
); }
1199 wxVariantDataDateTime(const DATE_STRUCT
* valptr
)
1200 { m_value
= wxDateTime(valptr
->day
, (wxDateTime::Month
) (valptr
->month
- 1),valptr
->year
); }
1201 wxVariantDataDateTime(const TIMESTAMP_STRUCT
* valptr
)
1202 { m_value
= wxDateTime(valptr
->day
, (wxDateTime::Month
) (valptr
->month
- 1), valptr
->year
,
1203 valptr
->hour
, valptr
->minute
, valptr
->second
, (wxDateTime::wxDateTime_t
)valptr
->fraction
); }
1206 inline wxDateTime
GetValue() const { return m_value
; }
1207 inline void SetValue(const wxDateTime
& value
) { m_value
= value
; }
1209 virtual bool Eq(wxVariantData
& data
) const;
1210 #if wxUSE_STD_IOSTREAM
1211 virtual bool Write(wxSTD ostream
& str
) const;
1213 virtual bool Write(wxString
& str
) const;
1214 #if wxUSE_STD_IOSTREAM
1215 virtual bool Read(wxSTD istream
& str
);
1217 virtual bool Read(wxString
& str
);
1218 virtual wxString
GetType() const { return wxT("datetime"); }
1219 virtual wxVariantData
* Clone() { return new wxVariantDataDateTime
; }
1226 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime
, wxVariantData
)
1228 bool wxVariantDataDateTime::Eq(wxVariantData
& data
) const
1230 wxASSERT_MSG( (data
.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
1232 wxVariantDataDateTime
& otherData
= (wxVariantDataDateTime
&) data
;
1234 return (otherData
.m_value
== m_value
);
1238 #if wxUSE_STD_IOSTREAM
1239 bool wxVariantDataDateTime::Write(wxSTD ostream
& str
) const
1243 str
<< value
.c_str();
1249 bool wxVariantDataDateTime::Write(wxString
& str
) const
1251 str
= m_value
.Format();
1256 #if wxUSE_STD_IOSTREAM
1257 bool wxVariantDataDateTime::Read(wxSTD istream
& WXUNUSED(str
))
1265 bool wxVariantDataDateTime::Read(wxString
& str
)
1267 if(! m_value
.ParseDateTime(str
.c_str()/*FIXME-UTF8*/))
1274 wxVariant::wxVariant(const wxDateTime
& val
, const wxString
& name
) // Date
1276 m_data
= new wxVariantDataDateTime(val
);
1281 wxVariant::wxVariant(const TIME_STRUCT
* valptr
, const wxString
& name
) // Date
1283 m_data
= new wxVariantDataDateTime(valptr
);
1287 wxVariant::wxVariant(const TIMESTAMP_STRUCT
* valptr
, const wxString
& name
) // Date
1289 m_data
= new wxVariantDataDateTime(valptr
);
1293 wxVariant::wxVariant(const DATE_STRUCT
* valptr
, const wxString
& name
) // Date
1295 m_data
= new wxVariantDataDateTime(valptr
);
1298 #endif // wxUSE_ODBC
1300 bool wxVariant::operator== (const wxDateTime
& value
) const
1302 wxDateTime thisValue
;
1303 if (!Convert(&thisValue
))
1306 return value
.IsEqualTo(thisValue
);
1309 bool wxVariant::operator!= (const wxDateTime
& value
) const
1311 return (!((*this) == value
));
1314 void wxVariant::operator= (const wxDateTime
& value
)
1316 if (GetType() == wxT("datetime") &&
1317 m_data
->GetRefCount() == 1)
1319 ((wxVariantDataDateTime
*)GetData())->SetValue(value
);
1324 m_data
= new wxVariantDataDateTime(value
);
1329 void wxVariant::operator= (const DATE_STRUCT
* value
)
1332 m_data
= new wxVariantDataDateTime(value
);
1335 void wxVariant::operator= (const TIME_STRUCT
* value
)
1338 m_data
= new wxVariantDataDateTime(value
);
1341 void wxVariant::operator= (const TIMESTAMP_STRUCT
* value
)
1344 m_data
= new wxVariantDataDateTime(value
);
1347 #endif // wxUSE_ODBC
1349 wxDateTime
wxVariant::GetDateTime() const
1352 if (!Convert(& value
))
1354 wxFAIL_MSG(wxT("Could not convert to a datetime"));
1360 #endif // wxUSE_DATETIME
1362 // ----------------------------------------------------------------------------
1363 // wxVariantDataArrayString
1364 // ----------------------------------------------------------------------------
1366 class wxVariantDataArrayString
: public wxVariantData
1369 wxVariantDataArrayString() { }
1370 wxVariantDataArrayString(const wxArrayString
& value
) { m_value
= value
; }
1372 wxArrayString
GetValue() const { return m_value
; }
1373 void SetValue(const wxArrayString
& value
) { m_value
= value
; }
1375 virtual bool Eq(wxVariantData
& data
) const;
1376 #if wxUSE_STD_IOSTREAM
1377 virtual bool Write(wxSTD ostream
& str
) const;
1379 virtual bool Write(wxString
& str
) const;
1380 #if wxUSE_STD_IOSTREAM
1381 virtual bool Read(wxSTD istream
& str
);
1383 virtual bool Read(wxString
& str
);
1384 virtual wxString
GetType() const { return wxT("arrstring"); }
1385 virtual wxVariantData
* Clone() { return new wxVariantDataArrayString
; }
1388 wxArrayString m_value
;
1390 DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString
)
1393 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString
, wxVariantData
)
1395 bool wxVariantDataArrayString::Eq(wxVariantData
& data
) const
1397 wxASSERT_MSG( data
.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
1399 wxVariantDataArrayString
& otherData
= (wxVariantDataArrayString
&) data
;
1401 return otherData
.m_value
== m_value
;
1404 #if wxUSE_STD_IOSTREAM
1405 bool wxVariantDataArrayString::Write(wxSTD ostream
& WXUNUSED(str
)) const
1412 bool wxVariantDataArrayString::Write(wxString
& str
) const
1414 size_t count
= m_value
.GetCount();
1415 for ( size_t n
= 0; n
< count
; n
++ )
1427 #if wxUSE_STD_IOSTREAM
1428 bool wxVariantDataArrayString::Read(wxSTD istream
& WXUNUSED(str
))
1436 bool wxVariantDataArrayString::Read(wxString
& str
)
1438 wxStringTokenizer
tk(str
, _T(";"));
1439 while ( tk
.HasMoreTokens() )
1441 m_value
.Add(tk
.GetNextToken());
1449 wxVariant::wxVariant(const wxArrayString
& val
, const wxString
& name
) // Strings
1451 m_data
= new wxVariantDataArrayString(val
);
1455 bool wxVariant::operator==(const wxArrayString
& WXUNUSED(value
)) const
1457 wxFAIL_MSG( _T("TODO") );
1462 bool wxVariant::operator!=(const wxArrayString
& value
) const
1464 return !(*this == value
);
1467 void wxVariant::operator=(const wxArrayString
& value
)
1469 if (GetType() == wxT("arrstring") &&
1470 m_data
->GetRefCount() == 1)
1472 ((wxVariantDataArrayString
*)GetData())->SetValue(value
);
1477 m_data
= new wxVariantDataArrayString(value
);
1481 wxArrayString
wxVariant::GetArrayString() const
1483 if ( GetType() == wxT("arrstring") )
1484 return ((wxVariantDataArrayString
*)GetData())->GetValue();
1486 return wxArrayString();
1489 // ----------------------------------------------------------------------------
1490 // wxVariantDataList
1491 // ----------------------------------------------------------------------------
1493 class WXDLLIMPEXP_BASE wxVariantDataList
: public wxVariantData
1495 DECLARE_DYNAMIC_CLASS(wxVariantDataList
)
1497 wxVariantDataList() {}
1498 wxVariantDataList(const wxList
& list
);
1499 virtual ~wxVariantDataList();
1501 wxList
& GetValue() { return m_value
; }
1502 void SetValue(const wxList
& value
) ;
1504 virtual bool Eq(wxVariantData
& data
) const;
1505 #if wxUSE_STD_IOSTREAM
1506 virtual bool Write(wxSTD ostream
& str
) const;
1508 virtual bool Write(wxString
& str
) const;
1509 #if wxUSE_STD_IOSTREAM
1510 virtual bool Read(wxSTD istream
& str
);
1512 virtual bool Read(wxString
& str
);
1513 virtual wxString
GetType() const { return wxT("list"); }
1521 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList
, wxVariantData
)
1523 wxVariantDataList::wxVariantDataList(const wxList
& list
)
1528 wxVariantDataList::~wxVariantDataList()
1533 void wxVariantDataList::SetValue(const wxList
& value
)
1536 wxList::compatibility_iterator node
= value
.GetFirst();
1539 wxVariant
* var
= (wxVariant
*) node
->GetData();
1540 m_value
.Append(new wxVariant(*var
));
1541 node
= node
->GetNext();
1545 void wxVariantDataList::Clear()
1547 wxList::compatibility_iterator node
= m_value
.GetFirst();
1550 wxVariant
* var
= (wxVariant
*) node
->GetData();
1552 node
= node
->GetNext();
1557 bool wxVariantDataList::Eq(wxVariantData
& data
) const
1559 wxASSERT_MSG( (data
.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
1561 wxVariantDataList
& listData
= (wxVariantDataList
&) data
;
1562 wxList::compatibility_iterator node1
= m_value
.GetFirst();
1563 wxList::compatibility_iterator node2
= listData
.GetValue().GetFirst();
1564 while (node1
&& node2
)
1566 wxVariant
* var1
= (wxVariant
*) node1
->GetData();
1567 wxVariant
* var2
= (wxVariant
*) node2
->GetData();
1568 if ((*var1
) != (*var2
))
1570 node1
= node1
->GetNext();
1571 node2
= node2
->GetNext();
1573 if (node1
|| node2
) return false;
1577 #if wxUSE_STD_IOSTREAM
1578 bool wxVariantDataList::Write(wxSTD ostream
& str
) const
1582 str
<< (const char*) s
.mb_str();
1587 bool wxVariantDataList::Write(wxString
& str
) const
1589 str
= wxEmptyString
;
1590 wxList::compatibility_iterator node
= m_value
.GetFirst();
1593 wxVariant
* var
= (wxVariant
*) node
->GetData();
1594 if (node
!= m_value
.GetFirst())
1597 str
+= var
->MakeString();
1598 node
= node
->GetNext();
1604 #if wxUSE_STD_IOSTREAM
1605 bool wxVariantDataList::Read(wxSTD istream
& WXUNUSED(str
))
1607 wxFAIL_MSG(wxT("Unimplemented"));
1613 bool wxVariantDataList::Read(wxString
& WXUNUSED(str
))
1615 wxFAIL_MSG(wxT("Unimplemented"));
1622 wxVariant::wxVariant(const wxList
& val
, const wxString
& name
) // List of variants
1624 m_data
= new wxVariantDataList(val
);
1628 bool wxVariant::operator== (const wxList
& value
) const
1630 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1632 wxVariantDataList
other(value
);
1633 return (GetData()->Eq(other
));
1636 bool wxVariant::operator!= (const wxList
& value
) const
1638 return (!((*this) == value
));
1641 void wxVariant::operator= (const wxList
& value
)
1643 if (GetType() == wxT("list") &&
1644 m_data
->GetRefCount() == 1)
1646 ((wxVariantDataList
*)GetData())->SetValue(value
);
1651 m_data
= new wxVariantDataList(value
);
1655 wxList
& wxVariant::GetList() const
1657 wxASSERT( (GetType() == wxT("list")) );
1659 return (wxList
&) ((wxVariantDataList
*) m_data
)->GetValue();
1663 void wxVariant::NullList()
1665 SetData(new wxVariantDataList());
1669 void wxVariant::Append(const wxVariant
& value
)
1671 wxList
& list
= GetList();
1673 list
.Append(new wxVariant(value
));
1676 // Insert at front of list
1677 void wxVariant::Insert(const wxVariant
& value
)
1679 wxList
& list
= GetList();
1681 list
.Insert(new wxVariant(value
));
1684 // Returns true if the variant is a member of the list
1685 bool wxVariant::Member(const wxVariant
& value
) const
1687 wxList
& list
= GetList();
1689 wxList::compatibility_iterator node
= list
.GetFirst();
1692 wxVariant
* other
= (wxVariant
*) node
->GetData();
1693 if (value
== *other
)
1695 node
= node
->GetNext();
1700 // Deletes the nth element of the list
1701 bool wxVariant::Delete(size_t item
)
1703 wxList
& list
= GetList();
1705 wxASSERT_MSG( (item
< list
.GetCount()), wxT("Invalid index to Delete") );
1706 wxList::compatibility_iterator node
= list
.Item(item
);
1707 wxVariant
* variant
= (wxVariant
*) node
->GetData();
1714 void wxVariant::ClearList()
1716 if (!IsNull() && (GetType() == wxT("list")))
1718 ((wxVariantDataList
*) m_data
)->Clear();
1722 if (!GetType().IsSameAs(wxT("list")))
1725 m_data
= new wxVariantDataList
;
1729 // Treat a list variant as an array
1730 wxVariant
wxVariant::operator[] (size_t idx
) const
1732 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
1734 if (GetType() == wxT("list"))
1736 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1737 wxASSERT_MSG( (idx
< data
->GetValue().GetCount()), wxT("Invalid index for array") );
1738 return * (wxVariant
*) (data
->GetValue().Item(idx
)->GetData());
1740 return wxNullVariant
;
1743 wxVariant
& wxVariant::operator[] (size_t idx
)
1745 // We can't return a reference to a variant for a string list, since the string
1746 // is actually stored as a char*, not a variant.
1748 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1750 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1751 wxASSERT_MSG( (idx
< data
->GetValue().GetCount()), wxT("Invalid index for array") );
1753 return * (wxVariant
*) (data
->GetValue().Item(idx
)->GetData());
1756 // Return the number of elements in a list
1757 size_t wxVariant::GetCount() const
1759 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
1761 if (GetType() == wxT("list"))
1763 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1764 return data
->GetValue().GetCount();
1769 // ----------------------------------------------------------------------------
1771 // ----------------------------------------------------------------------------
1773 bool wxVariant::Convert(long* value
) const
1775 wxString
type(GetType());
1776 if (type
== wxT("double"))
1777 *value
= (long) (((wxVariantDoubleData
*)GetData())->GetValue());
1778 else if (type
== wxT("long"))
1779 *value
= ((wxVariantDataLong
*)GetData())->GetValue();
1781 else if (type
== wxT("bool"))
1782 *value
= (long) (((wxVariantDataBool
*)GetData())->GetValue());
1784 else if (type
== wxT("string"))
1785 *value
= wxAtol(((wxVariantDataString
*)GetData())->GetValue());
1792 bool wxVariant::Convert(bool* value
) const
1794 wxString
type(GetType());
1795 if (type
== wxT("double"))
1796 *value
= ((int) (((wxVariantDoubleData
*)GetData())->GetValue()) != 0);
1797 else if (type
== wxT("long"))
1798 *value
= (((wxVariantDataLong
*)GetData())->GetValue() != 0);
1800 else if (type
== wxT("bool"))
1801 *value
= ((wxVariantDataBool
*)GetData())->GetValue();
1803 else if (type
== wxT("string"))
1805 wxString
val(((wxVariantDataString
*)GetData())->GetValue());
1807 if (val
== wxT("true") || val
== wxT("yes") || val
== wxT('1') )
1809 else if (val
== wxT("false") || val
== wxT("no") || val
== wxT('0') )
1820 bool wxVariant::Convert(double* value
) const
1822 wxString
type(GetType());
1823 if (type
== wxT("double"))
1824 *value
= ((wxVariantDoubleData
*)GetData())->GetValue();
1825 else if (type
== wxT("long"))
1826 *value
= (double) (((wxVariantDataLong
*)GetData())->GetValue());
1828 else if (type
== wxT("bool"))
1829 *value
= (double) (((wxVariantDataBool
*)GetData())->GetValue());
1831 else if (type
== wxT("string"))
1832 *value
= (double) wxAtof(((wxVariantDataString
*)GetData())->GetValue());
1839 bool wxVariant::Convert(wxUniChar
* value
) const
1841 wxString
type(GetType());
1842 if (type
== wxT("char"))
1843 *value
= ((wxVariantDataChar
*)GetData())->GetValue();
1844 else if (type
== wxT("long"))
1845 *value
= (char) (((wxVariantDataLong
*)GetData())->GetValue());
1847 else if (type
== wxT("bool"))
1848 *value
= (char) (((wxVariantDataBool
*)GetData())->GetValue());
1856 bool wxVariant::Convert(char* value
) const
1859 if ( !Convert(&ch
) )
1865 bool wxVariant::Convert(wchar_t* value
) const
1868 if ( !Convert(&ch
) )
1874 bool wxVariant::Convert(wxString
* value
) const
1876 *value
= MakeString();
1881 bool wxVariant::Convert(wxDateTime
* value
) const
1883 wxString
type(GetType());
1884 if (type
== wxT("datetime"))
1886 *value
= ((wxVariantDataDateTime
*)GetData())->GetValue();
1889 // Fallback to string conversion
1891 return Convert(&val
) &&
1892 (value
->ParseDateTime(val
.c_str()/*FIXME-UTF8*/) ||
1893 value
->ParseDate(val
.c_str()/*FIXME-UTF8*/) ||
1894 value
->ParseTime(val
.c_str()/*FIXME-UTF8*/));
1896 #endif // wxUSE_DATETIME
1898 #endif // wxUSE_VARIANT