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(wxChar value
) { m_value
= value
; }
648 inline wxChar
GetValue() const { return m_value
; }
649 inline void SetValue(wxChar 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
684 str
<< (const char*) s
.mb_str();
689 bool wxVariantDataChar::Write(wxString
& str
) const
691 str
.Printf(wxT("%c"), m_value
);
695 #if wxUSE_STD_IOSTREAM
696 bool wxVariantDataChar::Read(wxSTD istream
& WXUNUSED(str
))
698 wxFAIL_MSG(wxT("Unimplemented"));
705 bool wxVariantDataChar::Write(wxOutputStream
& str
) const
707 wxTextOutputStream
s(str
);
714 bool wxVariantDataChar::Read(wxInputStream
& str
)
716 wxTextInputStream
s(str
);
722 #endif // wxUSE_STREAMS
724 bool wxVariantDataChar::Read(wxString
& str
)
726 m_value
= str
[size_t(0)];
730 wxVariant::wxVariant(wxChar val
, const wxString
& name
)
732 m_data
= new wxVariantDataChar(val
);
736 bool wxVariant::operator== (wxChar value
) const
739 if (!Convert(&thisValue
))
742 return (value
== thisValue
);
745 bool wxVariant::operator!= (wxChar value
) const
747 return (!((*this) == value
));
750 void wxVariant::operator= (wxChar value
)
752 if (GetType() == wxT("char") &&
753 m_data
->GetRefCount() == 1)
755 ((wxVariantDataChar
*)GetData())->SetValue(value
);
760 m_data
= new wxVariantDataChar(value
);
764 wxChar
wxVariant::GetChar() const
767 if (Convert(& value
))
771 wxFAIL_MSG(wxT("Could not convert to a char"));
776 // ----------------------------------------------------------------------------
777 // wxVariantDataString
778 // ----------------------------------------------------------------------------
780 class WXDLLIMPEXP_BASE wxVariantDataString
: public wxVariantData
782 DECLARE_DYNAMIC_CLASS(wxVariantDataString
)
784 wxVariantDataString() { }
785 wxVariantDataString(const wxString
& value
) { m_value
= value
; }
787 inline wxString
GetValue() const { return m_value
; }
788 inline void SetValue(const wxString
& value
) { m_value
= value
; }
790 virtual bool Eq(wxVariantData
& data
) const;
791 #if wxUSE_STD_IOSTREAM
792 virtual bool Write(wxSTD ostream
& str
) const;
794 virtual bool Read(wxString
& str
);
795 virtual bool Write(wxString
& str
) const;
796 #if wxUSE_STD_IOSTREAM
797 virtual bool Read(wxSTD istream
& WXUNUSED(str
)) { return false; }
800 virtual bool Read(wxInputStream
& str
);
801 virtual bool Write(wxOutputStream
& str
) const;
802 #endif // wxUSE_STREAMS
803 virtual wxString
GetType() const { return wxT("string"); }
809 bool wxVariantDataString::Eq(wxVariantData
& data
) const
811 wxASSERT_MSG( (data
.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
813 wxVariantDataString
& otherData
= (wxVariantDataString
&) data
;
815 return (otherData
.m_value
== m_value
);
818 #if wxUSE_STD_IOSTREAM
819 bool wxVariantDataString::Write(wxSTD ostream
& str
) const
821 str
<< (const char*) m_value
.mb_str();
826 bool wxVariantDataString::Write(wxString
& str
) const
833 bool wxVariantDataString::Write(wxOutputStream
& str
) const
835 // why doesn't wxOutputStream::operator<< take "const wxString&"
836 wxTextOutputStream
s(str
);
837 s
.WriteString(m_value
);
841 bool wxVariantDataString::Read(wxInputStream
& str
)
843 wxTextInputStream
s(str
);
845 m_value
= s
.ReadLine();
848 #endif // wxUSE_STREAMS
850 bool wxVariantDataString::Read(wxString
& str
)
856 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString
, wxVariantData
)
860 wxVariant::wxVariant(const wxString
& val
, const wxString
& name
)
862 m_data
= new wxVariantDataString(val
);
866 wxVariant::wxVariant(const wxChar
* val
, const wxString
& name
)
868 m_data
= new wxVariantDataString(wxString(val
));
872 bool wxVariant::operator== (const wxString
& value
) const
875 if (!Convert(&thisValue
))
878 return value
== thisValue
;
881 bool wxVariant::operator!= (const wxString
& value
) const
883 return (!((*this) == value
));
886 void wxVariant::operator= (const wxString
& value
)
888 if (GetType() == wxT("string") &&
889 m_data
->GetRefCount() == 1)
891 ((wxVariantDataString
*)GetData())->SetValue(value
);
896 m_data
= new wxVariantDataString(value
);
900 void wxVariant::operator= (const wxChar
* value
)
902 if (GetType() == wxT("string") &&
903 m_data
->GetRefCount() == 1)
905 ((wxVariantDataString
*)GetData())->SetValue(wxString(value
));
910 m_data
= new wxVariantDataString(wxString(value
));
914 wxString
wxVariant::GetString() const
917 if (!Convert(& value
))
919 wxFAIL_MSG(wxT("Could not convert to a string"));
925 // ----------------------------------------------------------------------------
926 // wxVariantDataWxObjectPtr
927 // ----------------------------------------------------------------------------
929 class wxVariantDataWxObjectPtr
: public wxVariantData
931 DECLARE_DYNAMIC_CLASS(wxVariantDataWxObjectPtr
)
933 wxVariantDataWxObjectPtr() { }
934 wxVariantDataWxObjectPtr(wxObject
* value
) { m_value
= value
; }
936 inline wxObject
* GetValue() const { return m_value
; }
937 inline void SetValue(wxObject
* value
) { m_value
= value
; }
939 virtual bool Eq(wxVariantData
& data
) const;
940 #if wxUSE_STD_IOSTREAM
941 virtual bool Write(wxSTD ostream
& str
) const;
943 virtual bool Write(wxString
& str
) const;
944 #if wxUSE_STD_IOSTREAM
945 virtual bool Read(wxSTD istream
& str
);
947 virtual bool Read(wxString
& str
);
948 virtual wxString
GetType() const ;
949 virtual wxVariantData
* Clone() { return new wxVariantDataWxObjectPtr
; }
951 virtual wxClassInfo
* GetValueClassInfo() ;
955 DECLARE_NO_COPY_CLASS(wxVariantDataWxObjectPtr
)
958 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataWxObjectPtr
, wxVariantData
)
960 bool wxVariantDataWxObjectPtr::Eq(wxVariantData
& data
) const
962 wxASSERT_MSG( wxIsKindOf((&data
), wxVariantDataWxObjectPtr
), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
964 wxVariantDataWxObjectPtr
& otherData
= (wxVariantDataWxObjectPtr
&) data
;
966 return (otherData
.m_value
== m_value
);
969 wxString
wxVariantDataWxObjectPtr::GetType() const
971 wxString
returnVal(wxT("wxObject"));
973 returnVal
= m_value
->GetClassInfo()->GetClassName();
978 wxClassInfo
* wxVariantDataWxObjectPtr::GetValueClassInfo()
980 wxClassInfo
* returnVal
=NULL
;
982 if (m_value
) returnVal
= m_value
->GetClassInfo();
987 #if wxUSE_STD_IOSTREAM
988 bool wxVariantDataWxObjectPtr::Write(wxSTD ostream
& str
) const
992 str
<< (const char*) s
.mb_str();
997 bool wxVariantDataWxObjectPtr::Write(wxString
& str
) const
999 str
.Printf(wxT("%s(%p)"), GetType().c_str(), wx_static_cast(void*, m_value
));
1003 #if wxUSE_STD_IOSTREAM
1004 bool wxVariantDataWxObjectPtr::Read(wxSTD istream
& WXUNUSED(str
))
1011 bool wxVariantDataWxObjectPtr::Read(wxString
& WXUNUSED(str
))
1019 wxVariant::wxVariant( wxObject
* val
, const wxString
& name
)
1021 m_data
= new wxVariantDataWxObjectPtr(val
);
1025 bool wxVariant::operator== (wxObject
* value
) const
1027 return (value
== ((wxVariantDataWxObjectPtr
*)GetData())->GetValue());
1030 bool wxVariant::operator!= (wxObject
* value
) const
1032 return (!((*this) == (wxObject
*) value
));
1035 void wxVariant::operator= (wxObject
* value
)
1038 m_data
= new wxVariantDataWxObjectPtr(value
);
1041 wxObject
* wxVariant::GetWxObjectPtr() const
1043 wxASSERT(wxIsKindOf(GetData(), wxVariantDataWxObjectPtr
));
1044 return (wxObject
*) ((wxVariantDataWxObjectPtr
*) m_data
)->GetValue();
1047 // ----------------------------------------------------------------------------
1048 // wxVariantDataVoidPtr
1049 // ----------------------------------------------------------------------------
1051 class wxVariantDataVoidPtr
: public wxVariantData
1053 DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr
)
1055 wxVariantDataVoidPtr() { }
1056 wxVariantDataVoidPtr(void* value
) { m_value
= value
; }
1058 inline void* GetValue() const { return m_value
; }
1059 inline void SetValue(void* value
) { m_value
= value
; }
1061 virtual bool Eq(wxVariantData
& data
) const;
1062 #if wxUSE_STD_IOSTREAM
1063 virtual bool Write(wxSTD ostream
& str
) const;
1065 virtual bool Write(wxString
& str
) const;
1066 #if wxUSE_STD_IOSTREAM
1067 virtual bool Read(wxSTD istream
& str
);
1069 virtual bool Read(wxString
& str
);
1070 virtual wxString
GetType() const { return wxT("void*"); }
1071 virtual wxVariantData
* Clone() { return new wxVariantDataVoidPtr
; }
1076 DECLARE_NO_COPY_CLASS(wxVariantDataVoidPtr
)
1079 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr
, wxVariantData
)
1081 bool wxVariantDataVoidPtr::Eq(wxVariantData
& data
) const
1083 wxASSERT_MSG( (data
.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
1085 wxVariantDataVoidPtr
& otherData
= (wxVariantDataVoidPtr
&) data
;
1087 return (otherData
.m_value
== m_value
);
1090 #if wxUSE_STD_IOSTREAM
1091 bool wxVariantDataVoidPtr::Write(wxSTD ostream
& str
) const
1095 str
<< (const char*) s
.mb_str();
1100 bool wxVariantDataVoidPtr::Write(wxString
& str
) const
1102 str
.Printf(wxT("%p"), m_value
);
1106 #if wxUSE_STD_IOSTREAM
1107 bool wxVariantDataVoidPtr::Read(wxSTD istream
& WXUNUSED(str
))
1114 bool wxVariantDataVoidPtr::Read(wxString
& WXUNUSED(str
))
1122 wxVariant::wxVariant( void* val
, const wxString
& name
)
1124 m_data
= new wxVariantDataVoidPtr(val
);
1128 bool wxVariant::operator== (void* value
) const
1130 return (value
== ((wxVariantDataVoidPtr
*)GetData())->GetValue());
1133 bool wxVariant::operator!= (void* value
) const
1135 return (!((*this) == (void*) value
));
1138 void wxVariant::operator= (void* value
)
1140 if (GetType() == wxT("void*") &&
1141 m_data
->GetRefCount() == 1)
1143 ((wxVariantDataVoidPtr
*)GetData())->SetValue(value
);
1148 m_data
= new wxVariantDataVoidPtr(value
);
1152 void* wxVariant::GetVoidPtr() const
1154 wxASSERT( (GetType() == wxT("void*")) );
1156 return (void*) ((wxVariantDataVoidPtr
*) m_data
)->GetValue();
1159 // ----------------------------------------------------------------------------
1160 // wxVariantDataDateTime
1161 // ----------------------------------------------------------------------------
1165 class wxVariantDataDateTime
: public wxVariantData
1167 DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime
)
1170 wxVariantDataDateTime() { }
1171 wxVariantDataDateTime(const wxDateTime
& value
) { m_value
= value
; }
1173 wxVariantDataDateTime(const TIME_STRUCT
* valptr
)
1174 { m_value
= wxDateTime(valptr
->hour
, valptr
->minute
, valptr
->second
); }
1175 wxVariantDataDateTime(const DATE_STRUCT
* valptr
)
1176 { m_value
= wxDateTime(valptr
->day
, (wxDateTime::Month
) (valptr
->month
- 1),valptr
->year
); }
1177 wxVariantDataDateTime(const TIMESTAMP_STRUCT
* valptr
)
1178 { m_value
= wxDateTime(valptr
->day
, (wxDateTime::Month
) (valptr
->month
- 1), valptr
->year
,
1179 valptr
->hour
, valptr
->minute
, valptr
->second
, (wxDateTime::wxDateTime_t
)valptr
->fraction
); }
1182 inline wxDateTime
GetValue() const { return m_value
; }
1183 inline void SetValue(const wxDateTime
& value
) { m_value
= value
; }
1185 virtual bool Eq(wxVariantData
& data
) const;
1186 #if wxUSE_STD_IOSTREAM
1187 virtual bool Write(wxSTD ostream
& str
) const;
1189 virtual bool Write(wxString
& str
) const;
1190 #if wxUSE_STD_IOSTREAM
1191 virtual bool Read(wxSTD istream
& str
);
1193 virtual bool Read(wxString
& str
);
1194 virtual wxString
GetType() const { return wxT("datetime"); }
1195 virtual wxVariantData
* Clone() { return new wxVariantDataDateTime
; }
1202 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime
, wxVariantData
)
1204 bool wxVariantDataDateTime::Eq(wxVariantData
& data
) const
1206 wxASSERT_MSG( (data
.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
1208 wxVariantDataDateTime
& otherData
= (wxVariantDataDateTime
&) data
;
1210 return (otherData
.m_value
== m_value
);
1214 #if wxUSE_STD_IOSTREAM
1215 bool wxVariantDataDateTime::Write(wxSTD ostream
& str
) const
1219 str
<< value
.c_str();
1225 bool wxVariantDataDateTime::Write(wxString
& str
) const
1227 str
= m_value
.Format();
1232 #if wxUSE_STD_IOSTREAM
1233 bool wxVariantDataDateTime::Read(wxSTD istream
& WXUNUSED(str
))
1241 bool wxVariantDataDateTime::Read(wxString
& str
)
1243 if(! m_value
.ParseDateTime(str
.c_str()/*FIXME-UTF8*/))
1250 wxVariant::wxVariant(const wxDateTime
& val
, const wxString
& name
) // Date
1252 m_data
= new wxVariantDataDateTime(val
);
1257 wxVariant::wxVariant(const TIME_STRUCT
* valptr
, const wxString
& name
) // Date
1259 m_data
= new wxVariantDataDateTime(valptr
);
1263 wxVariant::wxVariant(const TIMESTAMP_STRUCT
* valptr
, const wxString
& name
) // Date
1265 m_data
= new wxVariantDataDateTime(valptr
);
1269 wxVariant::wxVariant(const DATE_STRUCT
* valptr
, const wxString
& name
) // Date
1271 m_data
= new wxVariantDataDateTime(valptr
);
1274 #endif // wxUSE_ODBC
1276 bool wxVariant::operator== (const wxDateTime
& value
) const
1278 wxDateTime thisValue
;
1279 if (!Convert(&thisValue
))
1282 return value
.IsEqualTo(thisValue
);
1285 bool wxVariant::operator!= (const wxDateTime
& value
) const
1287 return (!((*this) == value
));
1290 void wxVariant::operator= (const wxDateTime
& value
)
1292 if (GetType() == wxT("datetime") &&
1293 m_data
->GetRefCount() == 1)
1295 ((wxVariantDataDateTime
*)GetData())->SetValue(value
);
1300 m_data
= new wxVariantDataDateTime(value
);
1305 void wxVariant::operator= (const DATE_STRUCT
* value
)
1308 m_data
= new wxVariantDataDateTime(value
);
1311 void wxVariant::operator= (const TIME_STRUCT
* value
)
1314 m_data
= new wxVariantDataDateTime(value
);
1317 void wxVariant::operator= (const TIMESTAMP_STRUCT
* value
)
1320 m_data
= new wxVariantDataDateTime(value
);
1323 #endif // wxUSE_ODBC
1325 wxDateTime
wxVariant::GetDateTime() const
1328 if (!Convert(& value
))
1330 wxFAIL_MSG(wxT("Could not convert to a datetime"));
1336 #endif // wxUSE_DATETIME
1338 // ----------------------------------------------------------------------------
1339 // wxVariantDataArrayString
1340 // ----------------------------------------------------------------------------
1342 class wxVariantDataArrayString
: public wxVariantData
1345 wxVariantDataArrayString() { }
1346 wxVariantDataArrayString(const wxArrayString
& value
) { m_value
= value
; }
1348 wxArrayString
GetValue() const { return m_value
; }
1349 void SetValue(const wxArrayString
& value
) { m_value
= value
; }
1351 virtual bool Eq(wxVariantData
& data
) const;
1352 #if wxUSE_STD_IOSTREAM
1353 virtual bool Write(wxSTD ostream
& str
) const;
1355 virtual bool Write(wxString
& str
) const;
1356 #if wxUSE_STD_IOSTREAM
1357 virtual bool Read(wxSTD istream
& str
);
1359 virtual bool Read(wxString
& str
);
1360 virtual wxString
GetType() const { return wxT("arrstring"); }
1361 virtual wxVariantData
* Clone() { return new wxVariantDataArrayString
; }
1364 wxArrayString m_value
;
1366 DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString
)
1369 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString
, wxVariantData
)
1371 bool wxVariantDataArrayString::Eq(wxVariantData
& data
) const
1373 wxASSERT_MSG( data
.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
1375 wxVariantDataArrayString
& otherData
= (wxVariantDataArrayString
&) data
;
1377 return otherData
.m_value
== m_value
;
1380 #if wxUSE_STD_IOSTREAM
1381 bool wxVariantDataArrayString::Write(wxSTD ostream
& WXUNUSED(str
)) const
1388 bool wxVariantDataArrayString::Write(wxString
& str
) const
1390 size_t count
= m_value
.GetCount();
1391 for ( size_t n
= 0; n
< count
; n
++ )
1403 #if wxUSE_STD_IOSTREAM
1404 bool wxVariantDataArrayString::Read(wxSTD istream
& WXUNUSED(str
))
1412 bool wxVariantDataArrayString::Read(wxString
& str
)
1414 wxStringTokenizer
tk(str
, _T(";"));
1415 while ( tk
.HasMoreTokens() )
1417 m_value
.Add(tk
.GetNextToken());
1425 wxVariant::wxVariant(const wxArrayString
& val
, const wxString
& name
) // Strings
1427 m_data
= new wxVariantDataArrayString(val
);
1431 bool wxVariant::operator==(const wxArrayString
& WXUNUSED(value
)) const
1433 wxFAIL_MSG( _T("TODO") );
1438 bool wxVariant::operator!=(const wxArrayString
& value
) const
1440 return !(*this == value
);
1443 void wxVariant::operator=(const wxArrayString
& value
)
1445 if (GetType() == wxT("arrstring") &&
1446 m_data
->GetRefCount() == 1)
1448 ((wxVariantDataArrayString
*)GetData())->SetValue(value
);
1453 m_data
= new wxVariantDataArrayString(value
);
1457 wxArrayString
wxVariant::GetArrayString() const
1459 if ( GetType() == wxT("arrstring") )
1460 return ((wxVariantDataArrayString
*)GetData())->GetValue();
1462 return wxArrayString();
1465 // ----------------------------------------------------------------------------
1466 // wxVariantDataList
1467 // ----------------------------------------------------------------------------
1469 class WXDLLIMPEXP_BASE wxVariantDataList
: public wxVariantData
1471 DECLARE_DYNAMIC_CLASS(wxVariantDataList
)
1473 wxVariantDataList() {}
1474 wxVariantDataList(const wxList
& list
);
1475 virtual ~wxVariantDataList();
1477 wxList
& GetValue() { return m_value
; }
1478 void SetValue(const wxList
& value
) ;
1480 virtual bool Eq(wxVariantData
& data
) const;
1481 #if wxUSE_STD_IOSTREAM
1482 virtual bool Write(wxSTD ostream
& str
) const;
1484 virtual bool Write(wxString
& str
) const;
1485 #if wxUSE_STD_IOSTREAM
1486 virtual bool Read(wxSTD istream
& str
);
1488 virtual bool Read(wxString
& str
);
1489 virtual wxString
GetType() const { return wxT("list"); }
1497 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList
, wxVariantData
)
1499 wxVariantDataList::wxVariantDataList(const wxList
& list
)
1504 wxVariantDataList::~wxVariantDataList()
1509 void wxVariantDataList::SetValue(const wxList
& value
)
1512 wxList::compatibility_iterator node
= value
.GetFirst();
1515 wxVariant
* var
= (wxVariant
*) node
->GetData();
1516 m_value
.Append(new wxVariant(*var
));
1517 node
= node
->GetNext();
1521 void wxVariantDataList::Clear()
1523 wxList::compatibility_iterator node
= m_value
.GetFirst();
1526 wxVariant
* var
= (wxVariant
*) node
->GetData();
1528 node
= node
->GetNext();
1533 bool wxVariantDataList::Eq(wxVariantData
& data
) const
1535 wxASSERT_MSG( (data
.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
1537 wxVariantDataList
& listData
= (wxVariantDataList
&) data
;
1538 wxList::compatibility_iterator node1
= m_value
.GetFirst();
1539 wxList::compatibility_iterator node2
= listData
.GetValue().GetFirst();
1540 while (node1
&& node2
)
1542 wxVariant
* var1
= (wxVariant
*) node1
->GetData();
1543 wxVariant
* var2
= (wxVariant
*) node2
->GetData();
1544 if ((*var1
) != (*var2
))
1546 node1
= node1
->GetNext();
1547 node2
= node2
->GetNext();
1549 if (node1
|| node2
) return false;
1553 #if wxUSE_STD_IOSTREAM
1554 bool wxVariantDataList::Write(wxSTD ostream
& str
) const
1558 str
<< (const char*) s
.mb_str();
1563 bool wxVariantDataList::Write(wxString
& str
) const
1565 str
= wxEmptyString
;
1566 wxList::compatibility_iterator node
= m_value
.GetFirst();
1569 wxVariant
* var
= (wxVariant
*) node
->GetData();
1570 if (node
!= m_value
.GetFirst())
1573 str
+= var
->MakeString();
1574 node
= node
->GetNext();
1580 #if wxUSE_STD_IOSTREAM
1581 bool wxVariantDataList::Read(wxSTD istream
& WXUNUSED(str
))
1583 wxFAIL_MSG(wxT("Unimplemented"));
1589 bool wxVariantDataList::Read(wxString
& WXUNUSED(str
))
1591 wxFAIL_MSG(wxT("Unimplemented"));
1598 wxVariant::wxVariant(const wxList
& val
, const wxString
& name
) // List of variants
1600 m_data
= new wxVariantDataList(val
);
1604 bool wxVariant::operator== (const wxList
& value
) const
1606 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1608 wxVariantDataList
other(value
);
1609 return (GetData()->Eq(other
));
1612 bool wxVariant::operator!= (const wxList
& value
) const
1614 return (!((*this) == value
));
1617 void wxVariant::operator= (const wxList
& value
)
1619 if (GetType() == wxT("list") &&
1620 m_data
->GetRefCount() == 1)
1622 ((wxVariantDataList
*)GetData())->SetValue(value
);
1627 m_data
= new wxVariantDataList(value
);
1631 wxList
& wxVariant::GetList() const
1633 wxASSERT( (GetType() == wxT("list")) );
1635 return (wxList
&) ((wxVariantDataList
*) m_data
)->GetValue();
1639 void wxVariant::NullList()
1641 SetData(new wxVariantDataList());
1645 void wxVariant::Append(const wxVariant
& value
)
1647 wxList
& list
= GetList();
1649 list
.Append(new wxVariant(value
));
1652 // Insert at front of list
1653 void wxVariant::Insert(const wxVariant
& value
)
1655 wxList
& list
= GetList();
1657 list
.Insert(new wxVariant(value
));
1660 // Returns true if the variant is a member of the list
1661 bool wxVariant::Member(const wxVariant
& value
) const
1663 wxList
& list
= GetList();
1665 wxList::compatibility_iterator node
= list
.GetFirst();
1668 wxVariant
* other
= (wxVariant
*) node
->GetData();
1669 if (value
== *other
)
1671 node
= node
->GetNext();
1676 // Deletes the nth element of the list
1677 bool wxVariant::Delete(size_t item
)
1679 wxList
& list
= GetList();
1681 wxASSERT_MSG( (item
< list
.GetCount()), wxT("Invalid index to Delete") );
1682 wxList::compatibility_iterator node
= list
.Item(item
);
1683 wxVariant
* variant
= (wxVariant
*) node
->GetData();
1690 void wxVariant::ClearList()
1692 if (!IsNull() && (GetType() == wxT("list")))
1694 ((wxVariantDataList
*) m_data
)->Clear();
1698 if (!GetType().IsSameAs(wxT("list")))
1701 m_data
= new wxVariantDataList
;
1705 // Treat a list variant as an array
1706 wxVariant
wxVariant::operator[] (size_t idx
) const
1708 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
1710 if (GetType() == wxT("list"))
1712 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1713 wxASSERT_MSG( (idx
< data
->GetValue().GetCount()), wxT("Invalid index for array") );
1714 return * (wxVariant
*) (data
->GetValue().Item(idx
)->GetData());
1716 return wxNullVariant
;
1719 wxVariant
& wxVariant::operator[] (size_t idx
)
1721 // We can't return a reference to a variant for a string list, since the string
1722 // is actually stored as a char*, not a variant.
1724 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1726 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1727 wxASSERT_MSG( (idx
< data
->GetValue().GetCount()), wxT("Invalid index for array") );
1729 return * (wxVariant
*) (data
->GetValue().Item(idx
)->GetData());
1732 // Return the number of elements in a list
1733 size_t wxVariant::GetCount() const
1735 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
1737 if (GetType() == wxT("list"))
1739 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1740 return data
->GetValue().GetCount();
1745 // ----------------------------------------------------------------------------
1747 // ----------------------------------------------------------------------------
1749 bool wxVariant::Convert(long* value
) const
1751 wxString
type(GetType());
1752 if (type
== wxT("double"))
1753 *value
= (long) (((wxVariantDoubleData
*)GetData())->GetValue());
1754 else if (type
== wxT("long"))
1755 *value
= ((wxVariantDataLong
*)GetData())->GetValue();
1757 else if (type
== wxT("bool"))
1758 *value
= (long) (((wxVariantDataBool
*)GetData())->GetValue());
1760 else if (type
== wxT("string"))
1761 *value
= wxAtol(((wxVariantDataString
*)GetData())->GetValue());
1768 bool wxVariant::Convert(bool* value
) const
1770 wxString
type(GetType());
1771 if (type
== wxT("double"))
1772 *value
= ((int) (((wxVariantDoubleData
*)GetData())->GetValue()) != 0);
1773 else if (type
== wxT("long"))
1774 *value
= (((wxVariantDataLong
*)GetData())->GetValue() != 0);
1776 else if (type
== wxT("bool"))
1777 *value
= ((wxVariantDataBool
*)GetData())->GetValue();
1779 else if (type
== wxT("string"))
1781 wxString
val(((wxVariantDataString
*)GetData())->GetValue());
1783 if (val
== wxT("true") || val
== wxT("yes") || val
== wxT('1') )
1785 else if (val
== wxT("false") || val
== wxT("no") || val
== wxT('0') )
1796 bool wxVariant::Convert(double* value
) const
1798 wxString
type(GetType());
1799 if (type
== wxT("double"))
1800 *value
= ((wxVariantDoubleData
*)GetData())->GetValue();
1801 else if (type
== wxT("long"))
1802 *value
= (double) (((wxVariantDataLong
*)GetData())->GetValue());
1804 else if (type
== wxT("bool"))
1805 *value
= (double) (((wxVariantDataBool
*)GetData())->GetValue());
1807 else if (type
== wxT("string"))
1808 *value
= (double) wxAtof(((wxVariantDataString
*)GetData())->GetValue());
1815 bool wxVariant::Convert(wxChar
* value
) const
1817 wxString
type(GetType());
1818 if (type
== wxT("char"))
1819 *value
= ((wxVariantDataChar
*)GetData())->GetValue();
1820 else if (type
== wxT("long"))
1821 *value
= (char) (((wxVariantDataLong
*)GetData())->GetValue());
1823 else if (type
== wxT("bool"))
1824 *value
= (char) (((wxVariantDataBool
*)GetData())->GetValue());
1832 bool wxVariant::Convert(wxString
* value
) const
1834 *value
= MakeString();
1839 bool wxVariant::Convert(wxDateTime
* value
) const
1841 wxString
type(GetType());
1842 if (type
== wxT("datetime"))
1844 *value
= ((wxVariantDataDateTime
*)GetData())->GetValue();
1847 // Fallback to string conversion
1849 return Convert(&val
) &&
1850 (value
->ParseDateTime(val
.c_str()/*FIXME-UTF8*/) ||
1851 value
->ParseDate(val
.c_str()/*FIXME-UTF8*/) ||
1852 value
->ParseTime(val
.c_str()/*FIXME-UTF8*/));
1854 #endif // wxUSE_DATETIME
1856 #endif // wxUSE_VARIANT