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 wxVariant WXDLLIMPEXP_BASE wxNullVariant
;
55 #include "wx/listimpl.cpp"
56 WX_DEFINE_LIST(wxVariantList
);
62 IMPLEMENT_DYNAMIC_CLASS(wxVariant
, wxObject
)
64 wxVariant::wxVariant()
66 m_data
= (wxVariantData
*) NULL
;
69 bool wxVariant::IsNull() const
71 return (m_data
== (wxVariantData
*) NULL
);
74 void wxVariant::MakeNull()
79 void wxVariant::Clear()
81 m_name
= wxEmptyString
;
84 wxVariant::wxVariant(const wxVariant
& variant
)
87 m_data
= (wxVariantData
*) NULL
;
89 if (!variant
.IsNull())
92 m_name
= variant
.m_name
;
95 wxVariant::wxVariant(wxVariantData
* data
, const wxString
& name
) // User-defined data
101 wxVariant::~wxVariant()
107 void wxVariant::operator= (const wxVariant
& variant
)
110 m_name
= variant
.m_name
;
113 // myVariant = new wxStringVariantData("hello")
114 void wxVariant::operator= (wxVariantData
* variantData
)
117 m_data
= variantData
;
120 bool wxVariant::operator== (const wxVariant
& variant
) const
122 if (IsNull() || variant
.IsNull())
123 return (IsNull() == variant
.IsNull());
125 return (GetData()->Eq(* variant
.GetData()));
128 bool wxVariant::operator!= (const wxVariant
& variant
) const
130 return (!(*this == variant
));
134 wxString
wxVariant::MakeString() const
139 if (GetData()->Write(str
))
142 return wxEmptyString
;
145 void wxVariant::SetData(wxVariantData
* data
)
151 void wxVariant::Ref(const wxVariant
& clone
)
153 // nothing to be done
154 if (m_data
== clone
.m_data
)
157 // delete reference to old data
160 // reference new data
163 m_data
= clone
.m_data
;
169 void wxVariant::UnRef()
173 wxASSERT_MSG( m_data
->m_count
> 0, _T("invalid ref data count") );
181 // Returns a string representing the type of the variant,
182 // e.g. "string", "bool", "list", "double", "long"
183 wxString
wxVariant::GetType() const
186 return wxString(wxT("null"));
188 return GetData()->GetType();
192 bool wxVariant::IsType(const wxString
& type
) const
194 return (GetType() == type
);
197 bool wxVariant::IsValueKindOf(const wxClassInfo
* type
) const
199 wxClassInfo
* info
=GetData()->GetValueClassInfo();
200 return info
? info
->IsKindOf(type
) : false ;
204 // -----------------------------------------------------------------
206 // -----------------------------------------------------------------
208 class WXDLLIMPEXP_BASE wxVariantDataLong
: public wxVariantData
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 bool wxVariantDataLong::Eq(wxVariantData
& data
) const
238 wxASSERT_MSG( (data
.GetType() == wxT("long")), wxT("wxVariantDataLong::Eq: argument mismatch") );
240 wxVariantDataLong
& otherData
= (wxVariantDataLong
&) data
;
242 return (otherData
.m_value
== m_value
);
245 #if wxUSE_STD_IOSTREAM
246 bool wxVariantDataLong::Write(wxSTD ostream
& str
) const
250 str
<< (const char*) s
.mb_str();
255 bool wxVariantDataLong::Write(wxString
& str
) const
257 str
.Printf(wxT("%ld"), m_value
);
261 #if wxUSE_STD_IOSTREAM
262 bool wxVariantDataLong::Read(wxSTD istream
& str
)
270 bool wxVariantDataLong::Write(wxOutputStream
& str
) const
272 wxTextOutputStream
s(str
);
274 s
.Write32((size_t)m_value
);
278 bool wxVariantDataLong::Read(wxInputStream
& str
)
280 wxTextInputStream
s(str
);
281 m_value
= s
.Read32();
284 #endif // wxUSE_STREAMS
286 bool wxVariantDataLong::Read(wxString
& str
)
288 m_value
= wxAtol(str
);
294 wxVariant::wxVariant(long val
, const wxString
& name
)
296 m_data
= new wxVariantDataLong(val
);
300 wxVariant::wxVariant(int val
, const wxString
& name
)
302 m_data
= new wxVariantDataLong((long)val
);
306 wxVariant::wxVariant(short val
, const wxString
& name
)
308 m_data
= new wxVariantDataLong((long)val
);
312 bool wxVariant::operator== (long value
) const
315 if (!Convert(&thisValue
))
318 return (value
== thisValue
);
321 bool wxVariant::operator!= (long value
) const
323 return (!((*this) == value
));
326 void wxVariant::operator= (long value
)
328 if (GetType() == wxT("long") &&
329 m_data
->GetRefCount() == 1)
331 ((wxVariantDataLong
*)GetData())->SetValue(value
);
336 m_data
= new wxVariantDataLong(value
);
340 long wxVariant::GetLong() const
343 if (Convert(& value
))
347 wxFAIL_MSG(wxT("Could not convert to a long"));
352 // -----------------------------------------------------------------
353 // wxVariantDoubleData
354 // -----------------------------------------------------------------
356 class WXDLLIMPEXP_BASE wxVariantDoubleData
: public wxVariantData
359 wxVariantDoubleData() { m_value
= 0.0; }
360 wxVariantDoubleData(double value
) { m_value
= value
; }
362 inline double GetValue() const { return m_value
; }
363 inline void SetValue(double value
) { m_value
= value
; }
365 virtual bool Eq(wxVariantData
& data
) const;
366 virtual bool Read(wxString
& str
);
367 #if wxUSE_STD_IOSTREAM
368 virtual bool Write(wxSTD ostream
& str
) const;
370 virtual bool Write(wxString
& str
) const;
371 #if wxUSE_STD_IOSTREAM
372 virtual bool Read(wxSTD istream
& str
);
375 virtual bool Read(wxInputStream
& str
);
376 virtual bool Write(wxOutputStream
&str
) const;
377 #endif // wxUSE_STREAMS
378 virtual wxString
GetType() const { return wxT("double"); }
384 bool wxVariantDoubleData::Eq(wxVariantData
& data
) const
386 wxASSERT_MSG( (data
.GetType() == wxT("double")), wxT("wxVariantDoubleData::Eq: argument mismatch") );
388 wxVariantDoubleData
& otherData
= (wxVariantDoubleData
&) data
;
390 return wxIsSameDouble(otherData
.m_value
, m_value
);
393 #if wxUSE_STD_IOSTREAM
394 bool wxVariantDoubleData::Write(wxSTD ostream
& str
) const
398 str
<< (const char*) s
.mb_str();
403 bool wxVariantDoubleData::Write(wxString
& str
) const
405 str
.Printf(wxT("%.14g"), m_value
);
409 #if wxUSE_STD_IOSTREAM
410 bool wxVariantDoubleData::Read(wxSTD istream
& str
)
418 bool wxVariantDoubleData::Write(wxOutputStream
& str
) const
420 wxTextOutputStream
s(str
);
421 s
.WriteDouble((double)m_value
);
425 bool wxVariantDoubleData::Read(wxInputStream
& str
)
427 wxTextInputStream
s(str
);
428 m_value
= (float)s
.ReadDouble();
431 #endif // wxUSE_STREAMS
433 bool wxVariantDoubleData::Read(wxString
& str
)
435 m_value
= wxAtof(str
);
439 // wxVariant double code
441 wxVariant::wxVariant(double val
, const wxString
& name
)
443 m_data
= new wxVariantDoubleData(val
);
447 bool wxVariant::operator== (double value
) const
450 if (!Convert(&thisValue
))
453 return wxIsSameDouble(value
, thisValue
);
456 bool wxVariant::operator!= (double value
) const
458 return (!((*this) == value
));
461 void wxVariant::operator= (double value
)
463 if (GetType() == wxT("double") &&
464 m_data
->GetRefCount() == 1)
466 ((wxVariantDoubleData
*)GetData())->SetValue(value
);
471 m_data
= new wxVariantDoubleData(value
);
475 double wxVariant::GetDouble() const
478 if (Convert(& value
))
482 wxFAIL_MSG(wxT("Could not convert to a double number"));
487 // -----------------------------------------------------------------
489 // -----------------------------------------------------------------
493 class WXDLLIMPEXP_BASE wxVariantDataBool
: public wxVariantData
496 wxVariantDataBool() { m_value
= 0; }
497 wxVariantDataBool(bool value
) { m_value
= value
; }
499 inline bool GetValue() const { return m_value
; }
500 inline void SetValue(bool value
) { m_value
= value
; }
502 virtual bool Eq(wxVariantData
& data
) const;
503 #if wxUSE_STD_IOSTREAM
504 virtual bool Write(wxSTD ostream
& str
) const;
506 virtual bool Write(wxString
& str
) const;
507 virtual bool Read(wxString
& str
);
508 #if wxUSE_STD_IOSTREAM
509 virtual bool Read(wxSTD istream
& str
);
512 virtual bool Read(wxInputStream
& str
);
513 virtual bool Write(wxOutputStream
& str
) const;
514 #endif // wxUSE_STREAMS
515 virtual wxString
GetType() const { return wxT("bool"); }
521 bool wxVariantDataBool::Eq(wxVariantData
& data
) const
523 wxASSERT_MSG( (data
.GetType() == wxT("bool")), wxT("wxVariantDataBool::Eq: argument mismatch") );
525 wxVariantDataBool
& otherData
= (wxVariantDataBool
&) data
;
527 return (otherData
.m_value
== m_value
);
530 #if wxUSE_STD_IOSTREAM
531 bool wxVariantDataBool::Write(wxSTD ostream
& str
) const
535 str
<< (const char*) s
.mb_str();
540 bool wxVariantDataBool::Write(wxString
& str
) const
542 str
.Printf(wxT("%d"), (int) m_value
);
546 #if wxUSE_STD_IOSTREAM
547 bool wxVariantDataBool::Read(wxSTD istream
& WXUNUSED(str
))
549 wxFAIL_MSG(wxT("Unimplemented"));
550 // str >> (long) m_value;
556 bool wxVariantDataBool::Write(wxOutputStream
& str
) const
558 wxTextOutputStream
s(str
);
564 bool wxVariantDataBool::Read(wxInputStream
& str
)
566 wxTextInputStream
s(str
);
568 m_value
= s
.Read8() != 0;
571 #endif // wxUSE_STREAMS
573 bool wxVariantDataBool::Read(wxString
& str
)
575 m_value
= (wxAtol(str
) != 0);
581 wxVariant::wxVariant(bool val
, const wxString
& name
)
583 m_data
= new wxVariantDataBool(val
);
587 bool wxVariant::operator== (bool value
) const
590 if (!Convert(&thisValue
))
593 return (value
== thisValue
);
596 bool wxVariant::operator!= (bool value
) const
598 return (!((*this) == value
));
601 void wxVariant::operator= (bool value
)
603 if (GetType() == wxT("bool") &&
604 m_data
->GetRefCount() == 1)
606 ((wxVariantDataBool
*)GetData())->SetValue(value
);
611 m_data
= new wxVariantDataBool(value
);
615 bool wxVariant::GetBool() const
618 if (Convert(& value
))
622 wxFAIL_MSG(wxT("Could not convert to a bool"));
629 // -----------------------------------------------------------------
631 // -----------------------------------------------------------------
633 class WXDLLIMPEXP_BASE wxVariantDataChar
: public wxVariantData
636 wxVariantDataChar() { m_value
= 0; }
637 wxVariantDataChar(const wxUniChar
& value
) { m_value
= value
; }
639 inline wxUniChar
GetValue() const { return m_value
; }
640 inline void SetValue(const wxUniChar
& value
) { m_value
= value
; }
642 virtual bool Eq(wxVariantData
& data
) const;
643 #if wxUSE_STD_IOSTREAM
644 virtual bool Read(wxSTD istream
& str
);
645 virtual bool Write(wxSTD ostream
& str
) const;
647 virtual bool Read(wxString
& str
);
648 virtual bool Write(wxString
& str
) const;
650 virtual bool Read(wxInputStream
& str
);
651 virtual bool Write(wxOutputStream
& str
) const;
652 #endif // wxUSE_STREAMS
653 virtual wxString
GetType() const { return wxT("char"); }
659 bool wxVariantDataChar::Eq(wxVariantData
& data
) const
661 wxASSERT_MSG( (data
.GetType() == wxT("char")), wxT("wxVariantDataChar::Eq: argument mismatch") );
663 wxVariantDataChar
& otherData
= (wxVariantDataChar
&) data
;
665 return (otherData
.m_value
== m_value
);
668 #if wxUSE_STD_IOSTREAM
669 bool wxVariantDataChar::Write(wxSTD ostream
& str
) const
671 str
<< wxString(m_value
);
676 bool wxVariantDataChar::Write(wxString
& str
) const
682 #if wxUSE_STD_IOSTREAM
683 bool wxVariantDataChar::Read(wxSTD istream
& WXUNUSED(str
))
685 wxFAIL_MSG(wxT("Unimplemented"));
692 bool wxVariantDataChar::Write(wxOutputStream
& str
) const
694 wxTextOutputStream
s(str
);
696 // FIXME-UTF8: this should be just "s << m_value;" after removal of
697 // ANSI build and addition of wxUniChar to wxTextOutputStream:
698 s
<< (wxChar
)m_value
;
703 bool wxVariantDataChar::Read(wxInputStream
& str
)
705 wxTextInputStream
s(str
);
707 // FIXME-UTF8: this should be just "s >> m_value;" after removal of
708 // ANSI build and addition of wxUniChar to wxTextInputStream:
715 #endif // wxUSE_STREAMS
717 bool wxVariantDataChar::Read(wxString
& str
)
723 wxVariant::wxVariant(const wxUniChar
& val
, const wxString
& name
)
725 m_data
= new wxVariantDataChar(val
);
729 wxVariant::wxVariant(char val
, const wxString
& name
)
731 m_data
= new wxVariantDataChar(val
);
735 wxVariant::wxVariant(wchar_t val
, const wxString
& name
)
737 m_data
= new wxVariantDataChar(val
);
741 bool wxVariant::operator==(const wxUniChar
& value
) const
744 if (!Convert(&thisValue
))
747 return (value
== thisValue
);
750 wxVariant
& wxVariant::operator=(const wxUniChar
& value
)
752 if (GetType() == wxT("char") &&
753 m_data
->GetRefCount() == 1)
755 ((wxVariantDataChar
*)GetData())->SetValue(value
);
760 m_data
= new wxVariantDataChar(value
);
766 wxUniChar
wxVariant::GetChar() const
769 if (Convert(& value
))
773 wxFAIL_MSG(wxT("Could not convert to a char"));
778 // ----------------------------------------------------------------------------
779 // wxVariantDataString
780 // ----------------------------------------------------------------------------
782 class WXDLLIMPEXP_BASE wxVariantDataString
: public wxVariantData
785 wxVariantDataString() { }
786 wxVariantDataString(const wxString
& value
) { m_value
= value
; }
788 inline wxString
GetValue() const { return m_value
; }
789 inline void SetValue(const wxString
& value
) { m_value
= value
; }
791 virtual bool Eq(wxVariantData
& data
) const;
792 #if wxUSE_STD_IOSTREAM
793 virtual bool Write(wxSTD ostream
& str
) const;
795 virtual bool Read(wxString
& str
);
796 virtual bool Write(wxString
& str
) const;
797 #if wxUSE_STD_IOSTREAM
798 virtual bool Read(wxSTD istream
& WXUNUSED(str
)) { return false; }
801 virtual bool Read(wxInputStream
& str
);
802 virtual bool Write(wxOutputStream
& str
) const;
803 #endif // wxUSE_STREAMS
804 virtual wxString
GetType() const { return wxT("string"); }
810 bool wxVariantDataString::Eq(wxVariantData
& data
) const
812 wxASSERT_MSG( (data
.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
814 wxVariantDataString
& otherData
= (wxVariantDataString
&) data
;
816 return (otherData
.m_value
== m_value
);
819 #if wxUSE_STD_IOSTREAM
820 bool wxVariantDataString::Write(wxSTD ostream
& str
) const
822 str
<< (const char*) m_value
.mb_str();
827 bool wxVariantDataString::Write(wxString
& str
) const
834 bool wxVariantDataString::Write(wxOutputStream
& str
) const
836 // why doesn't wxOutputStream::operator<< take "const wxString&"
837 wxTextOutputStream
s(str
);
838 s
.WriteString(m_value
);
842 bool wxVariantDataString::Read(wxInputStream
& str
)
844 wxTextInputStream
s(str
);
846 m_value
= s
.ReadLine();
849 #endif // wxUSE_STREAMS
851 bool wxVariantDataString::Read(wxString
& str
)
859 wxVariant::wxVariant(const wxString
& val
, const wxString
& name
)
861 m_data
= new wxVariantDataString(val
);
865 wxVariant::wxVariant(const char* val
, const wxString
& name
)
867 m_data
= new wxVariantDataString(wxString(val
));
871 wxVariant::wxVariant(const wchar_t* val
, const wxString
& name
)
873 m_data
= new wxVariantDataString(wxString(val
));
877 wxVariant::wxVariant(const wxCStrData
& val
, const wxString
& name
)
879 m_data
= new wxVariantDataString(val
.AsString());
883 wxVariant::wxVariant(const wxCharBuffer
& val
, const wxString
& name
)
885 m_data
= new wxVariantDataString(wxString(val
));
889 wxVariant::wxVariant(const wxWCharBuffer
& val
, const wxString
& name
)
891 m_data
= new wxVariantDataString(wxString(val
));
895 bool wxVariant::operator== (const wxString
& value
) const
898 if (!Convert(&thisValue
))
901 return value
== thisValue
;
904 bool wxVariant::operator!= (const wxString
& value
) const
906 return (!((*this) == value
));
909 wxVariant
& wxVariant::operator= (const wxString
& value
)
911 if (GetType() == wxT("string") &&
912 m_data
->GetRefCount() == 1)
914 ((wxVariantDataString
*)GetData())->SetValue(value
);
919 m_data
= new wxVariantDataString(value
);
924 wxString
wxVariant::GetString() const
927 if (!Convert(& value
))
929 wxFAIL_MSG(wxT("Could not convert to a string"));
935 // ----------------------------------------------------------------------------
936 // wxVariantDataWxObjectPtr
937 // ----------------------------------------------------------------------------
939 class wxVariantDataWxObjectPtr
: public wxVariantData
942 wxVariantDataWxObjectPtr() { }
943 wxVariantDataWxObjectPtr(wxObject
* value
) { m_value
= value
; }
945 inline wxObject
* GetValue() const { return m_value
; }
946 inline void SetValue(wxObject
* value
) { m_value
= value
; }
948 virtual bool Eq(wxVariantData
& data
) const;
949 #if wxUSE_STD_IOSTREAM
950 virtual bool Write(wxSTD ostream
& str
) const;
952 virtual bool Write(wxString
& str
) const;
953 #if wxUSE_STD_IOSTREAM
954 virtual bool Read(wxSTD istream
& str
);
956 virtual bool Read(wxString
& str
);
957 virtual wxString
GetType() const ;
958 virtual wxVariantData
* Clone() { return new wxVariantDataWxObjectPtr
; }
960 virtual wxClassInfo
* GetValueClassInfo();
966 bool wxVariantDataWxObjectPtr::Eq(wxVariantData
& data
) const
968 wxASSERT_MSG( data
.GetType() == GetType(), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
970 wxVariantDataWxObjectPtr
& otherData
= (wxVariantDataWxObjectPtr
&) data
;
972 return (otherData
.m_value
== m_value
);
975 wxString
wxVariantDataWxObjectPtr::GetType() const
977 wxString
returnVal(wxT("wxObject*"));
981 returnVal
= m_value
->GetClassInfo()->GetClassName();
982 returnVal
+= wxT("*");
988 wxClassInfo
* wxVariantDataWxObjectPtr::GetValueClassInfo()
990 wxClassInfo
* returnVal
=NULL
;
992 if (m_value
) returnVal
= m_value
->GetClassInfo();
997 #if wxUSE_STD_IOSTREAM
998 bool wxVariantDataWxObjectPtr::Write(wxSTD ostream
& str
) const
1002 str
<< (const char*) s
.mb_str();
1007 bool wxVariantDataWxObjectPtr::Write(wxString
& str
) const
1009 str
.Printf(wxT("%s(%p)"), GetType().c_str(), wx_static_cast(void*, m_value
));
1013 #if wxUSE_STD_IOSTREAM
1014 bool wxVariantDataWxObjectPtr::Read(wxSTD istream
& WXUNUSED(str
))
1021 bool wxVariantDataWxObjectPtr::Read(wxString
& WXUNUSED(str
))
1029 wxVariant::wxVariant( wxObject
* val
, const wxString
& name
)
1031 m_data
= new wxVariantDataWxObjectPtr(val
);
1035 bool wxVariant::operator== (wxObject
* value
) const
1037 return (value
== ((wxVariantDataWxObjectPtr
*)GetData())->GetValue());
1040 bool wxVariant::operator!= (wxObject
* value
) const
1042 return (!((*this) == (wxObject
*) value
));
1045 void wxVariant::operator= (wxObject
* value
)
1048 m_data
= new wxVariantDataWxObjectPtr(value
);
1051 wxObject
* wxVariant::GetWxObjectPtr() const
1053 return (wxObject
*) ((wxVariantDataWxObjectPtr
*) m_data
)->GetValue();
1056 // ----------------------------------------------------------------------------
1057 // wxVariantDataVoidPtr
1058 // ----------------------------------------------------------------------------
1060 class wxVariantDataVoidPtr
: public wxVariantData
1063 wxVariantDataVoidPtr() { }
1064 wxVariantDataVoidPtr(void* value
) { m_value
= value
; }
1066 inline void* GetValue() const { return m_value
; }
1067 inline void SetValue(void* value
) { m_value
= value
; }
1069 virtual bool Eq(wxVariantData
& data
) const;
1070 #if wxUSE_STD_IOSTREAM
1071 virtual bool Write(wxSTD ostream
& str
) const;
1073 virtual bool Write(wxString
& str
) const;
1074 #if wxUSE_STD_IOSTREAM
1075 virtual bool Read(wxSTD istream
& str
);
1077 virtual bool Read(wxString
& str
);
1078 virtual wxString
GetType() const { return wxT("void*"); }
1079 virtual wxVariantData
* Clone() { return new wxVariantDataVoidPtr
; }
1085 bool wxVariantDataVoidPtr::Eq(wxVariantData
& data
) const
1087 wxASSERT_MSG( data
.GetType() == wxT("void*"), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
1089 wxVariantDataVoidPtr
& otherData
= (wxVariantDataVoidPtr
&) data
;
1091 return (otherData
.m_value
== m_value
);
1094 #if wxUSE_STD_IOSTREAM
1095 bool wxVariantDataVoidPtr::Write(wxSTD ostream
& str
) const
1099 str
<< (const char*) s
.mb_str();
1104 bool wxVariantDataVoidPtr::Write(wxString
& str
) const
1106 str
.Printf(wxT("%p"), m_value
);
1110 #if wxUSE_STD_IOSTREAM
1111 bool wxVariantDataVoidPtr::Read(wxSTD istream
& WXUNUSED(str
))
1118 bool wxVariantDataVoidPtr::Read(wxString
& WXUNUSED(str
))
1126 wxVariant::wxVariant( void* val
, const wxString
& name
)
1128 m_data
= new wxVariantDataVoidPtr(val
);
1132 bool wxVariant::operator== (void* value
) const
1134 return (value
== ((wxVariantDataVoidPtr
*)GetData())->GetValue());
1137 bool wxVariant::operator!= (void* value
) const
1139 return (!((*this) == (void*) value
));
1142 void wxVariant::operator= (void* value
)
1144 if (GetType() == wxT("void*") && (m_data
->GetRefCount() == 1))
1146 ((wxVariantDataVoidPtr
*)GetData())->SetValue(value
);
1151 m_data
= new wxVariantDataVoidPtr(value
);
1155 void* wxVariant::GetVoidPtr() const
1157 wxASSERT( (GetType() == wxT("void*")) );
1159 return (void*) ((wxVariantDataVoidPtr
*) m_data
)->GetValue();
1162 // ----------------------------------------------------------------------------
1163 // wxVariantDataDateTime
1164 // ----------------------------------------------------------------------------
1168 class wxVariantDataDateTime
: public wxVariantData
1171 wxVariantDataDateTime() { }
1172 wxVariantDataDateTime(const wxDateTime
& value
) { m_value
= value
; }
1174 wxVariantDataDateTime(const TIME_STRUCT
* valptr
)
1175 { m_value
= wxDateTime(valptr
->hour
, valptr
->minute
, valptr
->second
); }
1176 wxVariantDataDateTime(const DATE_STRUCT
* valptr
)
1177 { m_value
= wxDateTime(valptr
->day
, (wxDateTime::Month
) (valptr
->month
- 1),valptr
->year
); }
1178 wxVariantDataDateTime(const TIMESTAMP_STRUCT
* valptr
)
1179 { m_value
= wxDateTime(valptr
->day
, (wxDateTime::Month
) (valptr
->month
- 1), valptr
->year
,
1180 valptr
->hour
, valptr
->minute
, valptr
->second
, (wxDateTime::wxDateTime_t
)valptr
->fraction
); }
1183 inline wxDateTime
GetValue() const { return m_value
; }
1184 inline void SetValue(const wxDateTime
& value
) { m_value
= value
; }
1186 virtual bool Eq(wxVariantData
& data
) const;
1187 #if wxUSE_STD_IOSTREAM
1188 virtual bool Write(wxSTD ostream
& str
) const;
1190 virtual bool Write(wxString
& str
) const;
1191 #if wxUSE_STD_IOSTREAM
1192 virtual bool Read(wxSTD istream
& str
);
1194 virtual bool Read(wxString
& str
);
1195 virtual wxString
GetType() const { return wxT("datetime"); }
1196 virtual wxVariantData
* Clone() { return new wxVariantDataDateTime
; }
1203 bool wxVariantDataDateTime::Eq(wxVariantData
& data
) const
1205 wxASSERT_MSG( (data
.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
1207 wxVariantDataDateTime
& otherData
= (wxVariantDataDateTime
&) data
;
1209 return (otherData
.m_value
== m_value
);
1213 #if wxUSE_STD_IOSTREAM
1214 bool wxVariantDataDateTime::Write(wxSTD ostream
& str
) const
1218 str
<< value
.c_str();
1224 bool wxVariantDataDateTime::Write(wxString
& str
) const
1226 str
= m_value
.Format();
1231 #if wxUSE_STD_IOSTREAM
1232 bool wxVariantDataDateTime::Read(wxSTD istream
& WXUNUSED(str
))
1240 bool wxVariantDataDateTime::Read(wxString
& str
)
1242 if(! m_value
.ParseDateTime(str
.c_str()/*FIXME-UTF8*/))
1249 wxVariant::wxVariant(const wxDateTime
& val
, const wxString
& name
) // Date
1251 m_data
= new wxVariantDataDateTime(val
);
1256 wxVariant::wxVariant(const TIME_STRUCT
* valptr
, const wxString
& name
) // Date
1258 m_data
= new wxVariantDataDateTime(valptr
);
1262 wxVariant::wxVariant(const TIMESTAMP_STRUCT
* valptr
, const wxString
& name
) // Date
1264 m_data
= new wxVariantDataDateTime(valptr
);
1268 wxVariant::wxVariant(const DATE_STRUCT
* valptr
, const wxString
& name
) // Date
1270 m_data
= new wxVariantDataDateTime(valptr
);
1273 #endif // wxUSE_ODBC
1275 bool wxVariant::operator== (const wxDateTime
& value
) const
1277 wxDateTime thisValue
;
1278 if (!Convert(&thisValue
))
1281 return value
.IsEqualTo(thisValue
);
1284 bool wxVariant::operator!= (const wxDateTime
& value
) const
1286 return (!((*this) == value
));
1289 void wxVariant::operator= (const wxDateTime
& value
)
1291 if (GetType() == wxT("datetime") &&
1292 m_data
->GetRefCount() == 1)
1294 ((wxVariantDataDateTime
*)GetData())->SetValue(value
);
1299 m_data
= new wxVariantDataDateTime(value
);
1304 void wxVariant::operator= (const DATE_STRUCT
* value
)
1307 m_data
= new wxVariantDataDateTime(value
);
1310 void wxVariant::operator= (const TIME_STRUCT
* value
)
1313 m_data
= new wxVariantDataDateTime(value
);
1316 void wxVariant::operator= (const TIMESTAMP_STRUCT
* value
)
1319 m_data
= new wxVariantDataDateTime(value
);
1322 #endif // wxUSE_ODBC
1324 wxDateTime
wxVariant::GetDateTime() const
1327 if (!Convert(& value
))
1329 wxFAIL_MSG(wxT("Could not convert to a datetime"));
1335 #endif // wxUSE_DATETIME
1337 // ----------------------------------------------------------------------------
1338 // wxVariantDataArrayString
1339 // ----------------------------------------------------------------------------
1341 class wxVariantDataArrayString
: public wxVariantData
1344 wxVariantDataArrayString() { }
1345 wxVariantDataArrayString(const wxArrayString
& value
) { m_value
= value
; }
1347 wxArrayString
GetValue() const { return m_value
; }
1348 void SetValue(const wxArrayString
& value
) { m_value
= value
; }
1350 virtual bool Eq(wxVariantData
& data
) const;
1351 #if wxUSE_STD_IOSTREAM
1352 virtual bool Write(wxSTD ostream
& str
) const;
1354 virtual bool Write(wxString
& str
) const;
1355 #if wxUSE_STD_IOSTREAM
1356 virtual bool Read(wxSTD istream
& str
);
1358 virtual bool Read(wxString
& str
);
1359 virtual wxString
GetType() const { return wxT("arrstring"); }
1360 virtual wxVariantData
* Clone() { return new wxVariantDataArrayString
; }
1363 wxArrayString m_value
;
1366 bool wxVariantDataArrayString::Eq(wxVariantData
& data
) const
1368 wxASSERT_MSG( data
.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
1370 wxVariantDataArrayString
& otherData
= (wxVariantDataArrayString
&) data
;
1372 return otherData
.m_value
== m_value
;
1375 #if wxUSE_STD_IOSTREAM
1376 bool wxVariantDataArrayString::Write(wxSTD ostream
& WXUNUSED(str
)) const
1383 bool wxVariantDataArrayString::Write(wxString
& str
) const
1385 size_t count
= m_value
.GetCount();
1386 for ( size_t n
= 0; n
< count
; n
++ )
1398 #if wxUSE_STD_IOSTREAM
1399 bool wxVariantDataArrayString::Read(wxSTD istream
& WXUNUSED(str
))
1407 bool wxVariantDataArrayString::Read(wxString
& str
)
1409 wxStringTokenizer
tk(str
, _T(";"));
1410 while ( tk
.HasMoreTokens() )
1412 m_value
.Add(tk
.GetNextToken());
1420 wxVariant::wxVariant(const wxArrayString
& val
, const wxString
& name
) // Strings
1422 m_data
= new wxVariantDataArrayString(val
);
1426 bool wxVariant::operator==(const wxArrayString
& WXUNUSED(value
)) const
1428 wxFAIL_MSG( _T("TODO") );
1433 bool wxVariant::operator!=(const wxArrayString
& value
) const
1435 return !(*this == value
);
1438 void wxVariant::operator=(const wxArrayString
& value
)
1440 if (GetType() == wxT("arrstring") &&
1441 m_data
->GetRefCount() == 1)
1443 ((wxVariantDataArrayString
*)GetData())->SetValue(value
);
1448 m_data
= new wxVariantDataArrayString(value
);
1452 wxArrayString
wxVariant::GetArrayString() const
1454 if ( GetType() == wxT("arrstring") )
1455 return ((wxVariantDataArrayString
*)GetData())->GetValue();
1457 return wxArrayString();
1460 // ----------------------------------------------------------------------------
1461 // wxVariantDataList
1462 // ----------------------------------------------------------------------------
1464 class WXDLLIMPEXP_BASE wxVariantDataList
: public wxVariantData
1467 wxVariantDataList() {}
1468 wxVariantDataList(const wxList
& list
);
1469 virtual ~wxVariantDataList();
1471 wxList
& GetValue() { return m_value
; }
1472 void SetValue(const wxList
& value
) ;
1474 virtual bool Eq(wxVariantData
& data
) const;
1475 #if wxUSE_STD_IOSTREAM
1476 virtual bool Write(wxSTD ostream
& str
) const;
1478 virtual bool Write(wxString
& str
) const;
1479 #if wxUSE_STD_IOSTREAM
1480 virtual bool Read(wxSTD istream
& str
);
1482 virtual bool Read(wxString
& str
);
1483 virtual wxString
GetType() const { return wxT("list"); }
1491 wxVariantDataList::wxVariantDataList(const wxList
& list
)
1496 wxVariantDataList::~wxVariantDataList()
1501 void wxVariantDataList::SetValue(const wxList
& value
)
1504 wxList::compatibility_iterator node
= value
.GetFirst();
1507 wxVariant
* var
= (wxVariant
*) node
->GetData();
1508 m_value
.Append(new wxVariant(*var
));
1509 node
= node
->GetNext();
1513 void wxVariantDataList::Clear()
1515 wxList::compatibility_iterator node
= m_value
.GetFirst();
1518 wxVariant
* var
= (wxVariant
*) node
->GetData();
1520 node
= node
->GetNext();
1525 bool wxVariantDataList::Eq(wxVariantData
& data
) const
1527 wxASSERT_MSG( (data
.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
1529 wxVariantDataList
& listData
= (wxVariantDataList
&) data
;
1530 wxList::compatibility_iterator node1
= m_value
.GetFirst();
1531 wxList::compatibility_iterator node2
= listData
.GetValue().GetFirst();
1532 while (node1
&& node2
)
1534 wxVariant
* var1
= (wxVariant
*) node1
->GetData();
1535 wxVariant
* var2
= (wxVariant
*) node2
->GetData();
1536 if ((*var1
) != (*var2
))
1538 node1
= node1
->GetNext();
1539 node2
= node2
->GetNext();
1541 if (node1
|| node2
) return false;
1545 #if wxUSE_STD_IOSTREAM
1546 bool wxVariantDataList::Write(wxSTD ostream
& str
) const
1550 str
<< (const char*) s
.mb_str();
1555 bool wxVariantDataList::Write(wxString
& str
) const
1557 str
= wxEmptyString
;
1558 wxList::compatibility_iterator node
= m_value
.GetFirst();
1561 wxVariant
* var
= (wxVariant
*) node
->GetData();
1562 if (node
!= m_value
.GetFirst())
1565 str
+= var
->MakeString();
1566 node
= node
->GetNext();
1572 #if wxUSE_STD_IOSTREAM
1573 bool wxVariantDataList::Read(wxSTD istream
& WXUNUSED(str
))
1575 wxFAIL_MSG(wxT("Unimplemented"));
1581 bool wxVariantDataList::Read(wxString
& WXUNUSED(str
))
1583 wxFAIL_MSG(wxT("Unimplemented"));
1590 wxVariant::wxVariant(const wxList
& val
, const wxString
& name
) // List of variants
1592 m_data
= new wxVariantDataList(val
);
1596 bool wxVariant::operator== (const wxList
& value
) const
1598 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1600 wxVariantDataList
other(value
);
1601 return (GetData()->Eq(other
));
1604 bool wxVariant::operator!= (const wxList
& value
) const
1606 return (!((*this) == value
));
1609 void wxVariant::operator= (const wxList
& value
)
1611 if (GetType() == wxT("list") &&
1612 m_data
->GetRefCount() == 1)
1614 ((wxVariantDataList
*)GetData())->SetValue(value
);
1619 m_data
= new wxVariantDataList(value
);
1623 wxList
& wxVariant::GetList() const
1625 wxASSERT( (GetType() == wxT("list")) );
1627 return (wxList
&) ((wxVariantDataList
*) m_data
)->GetValue();
1631 void wxVariant::NullList()
1633 SetData(new wxVariantDataList());
1637 void wxVariant::Append(const wxVariant
& value
)
1639 wxList
& list
= GetList();
1641 list
.Append(new wxVariant(value
));
1644 // Insert at front of list
1645 void wxVariant::Insert(const wxVariant
& value
)
1647 wxList
& list
= GetList();
1649 list
.Insert(new wxVariant(value
));
1652 // Returns true if the variant is a member of the list
1653 bool wxVariant::Member(const wxVariant
& value
) const
1655 wxList
& list
= GetList();
1657 wxList::compatibility_iterator node
= list
.GetFirst();
1660 wxVariant
* other
= (wxVariant
*) node
->GetData();
1661 if (value
== *other
)
1663 node
= node
->GetNext();
1668 // Deletes the nth element of the list
1669 bool wxVariant::Delete(size_t item
)
1671 wxList
& list
= GetList();
1673 wxASSERT_MSG( (item
< list
.GetCount()), wxT("Invalid index to Delete") );
1674 wxList::compatibility_iterator node
= list
.Item(item
);
1675 wxVariant
* variant
= (wxVariant
*) node
->GetData();
1682 void wxVariant::ClearList()
1684 if (!IsNull() && (GetType() == wxT("list")))
1686 ((wxVariantDataList
*) m_data
)->Clear();
1690 if (!GetType().IsSameAs(wxT("list")))
1693 m_data
= new wxVariantDataList
;
1697 // Treat a list variant as an array
1698 wxVariant
wxVariant::operator[] (size_t idx
) const
1700 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
1702 if (GetType() == wxT("list"))
1704 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1705 wxASSERT_MSG( (idx
< data
->GetValue().GetCount()), wxT("Invalid index for array") );
1706 return * (wxVariant
*) (data
->GetValue().Item(idx
)->GetData());
1708 return wxNullVariant
;
1711 wxVariant
& wxVariant::operator[] (size_t idx
)
1713 // We can't return a reference to a variant for a string list, since the string
1714 // is actually stored as a char*, not a variant.
1716 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1718 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1719 wxASSERT_MSG( (idx
< data
->GetValue().GetCount()), wxT("Invalid index for array") );
1721 return * (wxVariant
*) (data
->GetValue().Item(idx
)->GetData());
1724 // Return the number of elements in a list
1725 size_t wxVariant::GetCount() const
1727 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
1729 if (GetType() == wxT("list"))
1731 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1732 return data
->GetValue().GetCount();
1737 // ----------------------------------------------------------------------------
1739 // ----------------------------------------------------------------------------
1741 bool wxVariant::Convert(long* value
) const
1743 wxString
type(GetType());
1744 if (type
== wxT("double"))
1745 *value
= (long) (((wxVariantDoubleData
*)GetData())->GetValue());
1746 else if (type
== wxT("long"))
1747 *value
= ((wxVariantDataLong
*)GetData())->GetValue();
1749 else if (type
== wxT("bool"))
1750 *value
= (long) (((wxVariantDataBool
*)GetData())->GetValue());
1752 else if (type
== wxT("string"))
1753 *value
= wxAtol(((wxVariantDataString
*)GetData())->GetValue());
1760 bool wxVariant::Convert(bool* value
) const
1762 wxString
type(GetType());
1763 if (type
== wxT("double"))
1764 *value
= ((int) (((wxVariantDoubleData
*)GetData())->GetValue()) != 0);
1765 else if (type
== wxT("long"))
1766 *value
= (((wxVariantDataLong
*)GetData())->GetValue() != 0);
1768 else if (type
== wxT("bool"))
1769 *value
= ((wxVariantDataBool
*)GetData())->GetValue();
1771 else if (type
== wxT("string"))
1773 wxString
val(((wxVariantDataString
*)GetData())->GetValue());
1775 if (val
== wxT("true") || val
== wxT("yes") || val
== wxT('1') )
1777 else if (val
== wxT("false") || val
== wxT("no") || val
== wxT('0') )
1788 bool wxVariant::Convert(double* value
) const
1790 wxString
type(GetType());
1791 if (type
== wxT("double"))
1792 *value
= ((wxVariantDoubleData
*)GetData())->GetValue();
1793 else if (type
== wxT("long"))
1794 *value
= (double) (((wxVariantDataLong
*)GetData())->GetValue());
1796 else if (type
== wxT("bool"))
1797 *value
= (double) (((wxVariantDataBool
*)GetData())->GetValue());
1799 else if (type
== wxT("string"))
1800 *value
= (double) wxAtof(((wxVariantDataString
*)GetData())->GetValue());
1807 bool wxVariant::Convert(wxUniChar
* value
) const
1809 wxString
type(GetType());
1810 if (type
== wxT("char"))
1811 *value
= ((wxVariantDataChar
*)GetData())->GetValue();
1812 else if (type
== wxT("long"))
1813 *value
= (char) (((wxVariantDataLong
*)GetData())->GetValue());
1815 else if (type
== wxT("bool"))
1816 *value
= (char) (((wxVariantDataBool
*)GetData())->GetValue());
1824 bool wxVariant::Convert(char* value
) const
1827 if ( !Convert(&ch
) )
1833 bool wxVariant::Convert(wchar_t* value
) const
1836 if ( !Convert(&ch
) )
1842 bool wxVariant::Convert(wxString
* value
) const
1844 *value
= MakeString();
1849 bool wxVariant::Convert(wxDateTime
* value
) const
1851 wxString
type(GetType());
1852 if (type
== wxT("datetime"))
1854 *value
= ((wxVariantDataDateTime
*)GetData())->GetValue();
1857 // Fallback to string conversion
1859 return Convert(&val
) &&
1860 (value
->ParseDateTime(val
.c_str()/*FIXME-UTF8*/) ||
1861 value
->ParseDate(val
.c_str()/*FIXME-UTF8*/) ||
1862 value
->ParseTime(val
.c_str()/*FIXME-UTF8*/));
1864 #endif // wxUSE_DATETIME
1866 #endif // wxUSE_VARIANT