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
;
59 IMPLEMENT_DYNAMIC_CLASS(wxVariant
, wxObject
)
61 wxVariant::wxVariant()
63 m_data
= (wxVariantData
*) NULL
;
66 bool wxVariant::IsNull() const
68 return (m_data
== (wxVariantData
*) NULL
);
71 void wxVariant::MakeNull()
76 void wxVariant::Clear()
78 m_name
= wxEmptyString
;
81 wxVariant::wxVariant(const wxVariant
& variant
)
84 m_data
= (wxVariantData
*) NULL
;
86 if (!variant
.IsNull())
89 m_name
= variant
.m_name
;
92 wxVariant::wxVariant(wxVariantData
* data
, const wxString
& name
) // User-defined data
98 wxVariant::~wxVariant()
104 void wxVariant::operator= (const wxVariant
& variant
)
107 m_name
= variant
.m_name
;
110 // myVariant = new wxStringVariantData("hello")
111 void wxVariant::operator= (wxVariantData
* variantData
)
114 m_data
= variantData
;
117 bool wxVariant::operator== (const wxVariant
& variant
) const
119 if (IsNull() || variant
.IsNull())
120 return (IsNull() == variant
.IsNull());
122 return (GetData()->Eq(* variant
.GetData()));
125 bool wxVariant::operator!= (const wxVariant
& variant
) const
127 return (!(*this == variant
));
131 wxString
wxVariant::MakeString() const
136 if (GetData()->Write(str
))
139 return wxEmptyString
;
142 void wxVariant::SetData(wxVariantData
* data
)
148 void wxVariant::Ref(const wxVariant
& clone
)
150 // nothing to be done
151 if (m_data
== clone
.m_data
)
154 // delete reference to old data
157 // reference new data
160 m_data
= clone
.m_data
;
166 void wxVariant::UnRef()
170 wxASSERT_MSG( m_data
->m_count
> 0, _T("invalid ref data count") );
178 // Returns a string representing the type of the variant,
179 // e.g. "string", "bool", "list", "double", "long"
180 wxString
wxVariant::GetType() const
183 return wxString(wxT("null"));
185 return GetData()->GetType();
189 bool wxVariant::IsType(const wxString
& type
) const
191 return (GetType() == type
);
194 bool wxVariant::IsValueKindOf(const wxClassInfo
* type
) const
196 wxClassInfo
* info
=GetData()->GetValueClassInfo();
197 return info
? info
->IsKindOf(type
) : false ;
201 // -----------------------------------------------------------------
203 // -----------------------------------------------------------------
205 class WXDLLIMPEXP_BASE wxVariantDataLong
: public wxVariantData
208 wxVariantDataLong() { m_value
= 0; }
209 wxVariantDataLong(long value
) { m_value
= value
; }
211 inline long GetValue() const { return m_value
; }
212 inline void SetValue(long value
) { m_value
= value
; }
214 virtual bool Eq(wxVariantData
& data
) const;
216 virtual bool Read(wxString
& str
);
217 virtual bool Write(wxString
& str
) const;
218 #if wxUSE_STD_IOSTREAM
219 virtual bool Read(wxSTD istream
& str
);
220 virtual bool Write(wxSTD ostream
& str
) const;
223 virtual bool Read(wxInputStream
& str
);
224 virtual bool Write(wxOutputStream
&str
) const;
225 #endif // wxUSE_STREAMS
227 virtual wxString
GetType() const { return wxT("long"); }
233 bool wxVariantDataLong::Eq(wxVariantData
& data
) const
235 wxASSERT_MSG( (data
.GetType() == wxT("long")), wxT("wxVariantDataLong::Eq: argument mismatch") );
237 wxVariantDataLong
& otherData
= (wxVariantDataLong
&) data
;
239 return (otherData
.m_value
== m_value
);
242 #if wxUSE_STD_IOSTREAM
243 bool wxVariantDataLong::Write(wxSTD ostream
& str
) const
247 str
<< (const char*) s
.mb_str();
252 bool wxVariantDataLong::Write(wxString
& str
) const
254 str
.Printf(wxT("%ld"), m_value
);
258 #if wxUSE_STD_IOSTREAM
259 bool wxVariantDataLong::Read(wxSTD istream
& str
)
267 bool wxVariantDataLong::Write(wxOutputStream
& str
) const
269 wxTextOutputStream
s(str
);
271 s
.Write32((size_t)m_value
);
275 bool wxVariantDataLong::Read(wxInputStream
& str
)
277 wxTextInputStream
s(str
);
278 m_value
= s
.Read32();
281 #endif // wxUSE_STREAMS
283 bool wxVariantDataLong::Read(wxString
& str
)
285 m_value
= wxAtol(str
);
291 wxVariant::wxVariant(long val
, const wxString
& name
)
293 m_data
= new wxVariantDataLong(val
);
297 wxVariant::wxVariant(int val
, const wxString
& name
)
299 m_data
= new wxVariantDataLong((long)val
);
303 wxVariant::wxVariant(short val
, const wxString
& name
)
305 m_data
= new wxVariantDataLong((long)val
);
309 bool wxVariant::operator== (long value
) const
312 if (!Convert(&thisValue
))
315 return (value
== thisValue
);
318 bool wxVariant::operator!= (long value
) const
320 return (!((*this) == value
));
323 void wxVariant::operator= (long value
)
325 if (GetType() == wxT("long") &&
326 m_data
->GetRefCount() == 1)
328 ((wxVariantDataLong
*)GetData())->SetValue(value
);
333 m_data
= new wxVariantDataLong(value
);
337 long wxVariant::GetLong() const
340 if (Convert(& value
))
344 wxFAIL_MSG(wxT("Could not convert to a long"));
349 // -----------------------------------------------------------------
350 // wxVariantDoubleData
351 // -----------------------------------------------------------------
353 class WXDLLIMPEXP_BASE wxVariantDoubleData
: public wxVariantData
356 wxVariantDoubleData() { m_value
= 0.0; }
357 wxVariantDoubleData(double value
) { m_value
= value
; }
359 inline double GetValue() const { return m_value
; }
360 inline void SetValue(double value
) { m_value
= value
; }
362 virtual bool Eq(wxVariantData
& data
) const;
363 virtual bool Read(wxString
& str
);
364 #if wxUSE_STD_IOSTREAM
365 virtual bool Write(wxSTD ostream
& str
) const;
367 virtual bool Write(wxString
& str
) const;
368 #if wxUSE_STD_IOSTREAM
369 virtual bool Read(wxSTD istream
& str
);
372 virtual bool Read(wxInputStream
& str
);
373 virtual bool Write(wxOutputStream
&str
) const;
374 #endif // wxUSE_STREAMS
375 virtual wxString
GetType() const { return wxT("double"); }
381 bool wxVariantDoubleData::Eq(wxVariantData
& data
) const
383 wxASSERT_MSG( (data
.GetType() == wxT("double")), wxT("wxVariantDoubleData::Eq: argument mismatch") );
385 wxVariantDoubleData
& otherData
= (wxVariantDoubleData
&) data
;
387 return wxIsSameDouble(otherData
.m_value
, m_value
);
390 #if wxUSE_STD_IOSTREAM
391 bool wxVariantDoubleData::Write(wxSTD ostream
& str
) const
395 str
<< (const char*) s
.mb_str();
400 bool wxVariantDoubleData::Write(wxString
& str
) const
402 str
.Printf(wxT("%.14g"), m_value
);
406 #if wxUSE_STD_IOSTREAM
407 bool wxVariantDoubleData::Read(wxSTD istream
& str
)
415 bool wxVariantDoubleData::Write(wxOutputStream
& str
) const
417 wxTextOutputStream
s(str
);
418 s
.WriteDouble((double)m_value
);
422 bool wxVariantDoubleData::Read(wxInputStream
& str
)
424 wxTextInputStream
s(str
);
425 m_value
= (float)s
.ReadDouble();
428 #endif // wxUSE_STREAMS
430 bool wxVariantDoubleData::Read(wxString
& str
)
432 m_value
= wxAtof(str
);
436 // wxVariant double code
438 wxVariant::wxVariant(double val
, const wxString
& name
)
440 m_data
= new wxVariantDoubleData(val
);
444 bool wxVariant::operator== (double value
) const
447 if (!Convert(&thisValue
))
450 return wxIsSameDouble(value
, thisValue
);
453 bool wxVariant::operator!= (double value
) const
455 return (!((*this) == value
));
458 void wxVariant::operator= (double value
)
460 if (GetType() == wxT("double") &&
461 m_data
->GetRefCount() == 1)
463 ((wxVariantDoubleData
*)GetData())->SetValue(value
);
468 m_data
= new wxVariantDoubleData(value
);
472 double wxVariant::GetDouble() const
475 if (Convert(& value
))
479 wxFAIL_MSG(wxT("Could not convert to a double number"));
484 // -----------------------------------------------------------------
486 // -----------------------------------------------------------------
490 class WXDLLIMPEXP_BASE wxVariantDataBool
: public wxVariantData
493 wxVariantDataBool() { m_value
= 0; }
494 wxVariantDataBool(bool value
) { m_value
= value
; }
496 inline bool GetValue() const { return m_value
; }
497 inline void SetValue(bool value
) { m_value
= value
; }
499 virtual bool Eq(wxVariantData
& data
) const;
500 #if wxUSE_STD_IOSTREAM
501 virtual bool Write(wxSTD ostream
& str
) const;
503 virtual bool Write(wxString
& str
) const;
504 virtual bool Read(wxString
& str
);
505 #if wxUSE_STD_IOSTREAM
506 virtual bool Read(wxSTD istream
& str
);
509 virtual bool Read(wxInputStream
& str
);
510 virtual bool Write(wxOutputStream
& str
) const;
511 #endif // wxUSE_STREAMS
512 virtual wxString
GetType() const { return wxT("bool"); }
518 bool wxVariantDataBool::Eq(wxVariantData
& data
) const
520 wxASSERT_MSG( (data
.GetType() == wxT("bool")), wxT("wxVariantDataBool::Eq: argument mismatch") );
522 wxVariantDataBool
& otherData
= (wxVariantDataBool
&) data
;
524 return (otherData
.m_value
== m_value
);
527 #if wxUSE_STD_IOSTREAM
528 bool wxVariantDataBool::Write(wxSTD ostream
& str
) const
532 str
<< (const char*) s
.mb_str();
537 bool wxVariantDataBool::Write(wxString
& str
) const
539 str
.Printf(wxT("%d"), (int) m_value
);
543 #if wxUSE_STD_IOSTREAM
544 bool wxVariantDataBool::Read(wxSTD istream
& WXUNUSED(str
))
546 wxFAIL_MSG(wxT("Unimplemented"));
547 // str >> (long) m_value;
553 bool wxVariantDataBool::Write(wxOutputStream
& str
) const
555 wxTextOutputStream
s(str
);
561 bool wxVariantDataBool::Read(wxInputStream
& str
)
563 wxTextInputStream
s(str
);
565 m_value
= s
.Read8() != 0;
568 #endif // wxUSE_STREAMS
570 bool wxVariantDataBool::Read(wxString
& str
)
572 m_value
= (wxAtol(str
) != 0);
578 wxVariant::wxVariant(bool val
, const wxString
& name
)
580 m_data
= new wxVariantDataBool(val
);
584 bool wxVariant::operator== (bool value
) const
587 if (!Convert(&thisValue
))
590 return (value
== thisValue
);
593 bool wxVariant::operator!= (bool value
) const
595 return (!((*this) == value
));
598 void wxVariant::operator= (bool value
)
600 if (GetType() == wxT("bool") &&
601 m_data
->GetRefCount() == 1)
603 ((wxVariantDataBool
*)GetData())->SetValue(value
);
608 m_data
= new wxVariantDataBool(value
);
612 bool wxVariant::GetBool() const
615 if (Convert(& value
))
619 wxFAIL_MSG(wxT("Could not convert to a bool"));
626 // -----------------------------------------------------------------
628 // -----------------------------------------------------------------
630 class WXDLLIMPEXP_BASE wxVariantDataChar
: public wxVariantData
633 wxVariantDataChar() { m_value
= 0; }
634 wxVariantDataChar(const wxUniChar
& value
) { m_value
= value
; }
636 inline wxUniChar
GetValue() const { return m_value
; }
637 inline void SetValue(const wxUniChar
& value
) { m_value
= value
; }
639 virtual bool Eq(wxVariantData
& data
) const;
640 #if wxUSE_STD_IOSTREAM
641 virtual bool Read(wxSTD istream
& str
);
642 virtual bool Write(wxSTD ostream
& str
) const;
644 virtual bool Read(wxString
& str
);
645 virtual bool Write(wxString
& str
) const;
647 virtual bool Read(wxInputStream
& str
);
648 virtual bool Write(wxOutputStream
& str
) const;
649 #endif // wxUSE_STREAMS
650 virtual wxString
GetType() const { return wxT("char"); }
656 bool wxVariantDataChar::Eq(wxVariantData
& data
) const
658 wxASSERT_MSG( (data
.GetType() == wxT("char")), wxT("wxVariantDataChar::Eq: argument mismatch") );
660 wxVariantDataChar
& otherData
= (wxVariantDataChar
&) data
;
662 return (otherData
.m_value
== m_value
);
665 #if wxUSE_STD_IOSTREAM
666 bool wxVariantDataChar::Write(wxSTD ostream
& str
) const
668 str
<< wxString(m_value
);
673 bool wxVariantDataChar::Write(wxString
& str
) const
679 #if wxUSE_STD_IOSTREAM
680 bool wxVariantDataChar::Read(wxSTD istream
& WXUNUSED(str
))
682 wxFAIL_MSG(wxT("Unimplemented"));
689 bool wxVariantDataChar::Write(wxOutputStream
& str
) const
691 wxTextOutputStream
s(str
);
693 // FIXME-UTF8: this should be just "s << m_value;" after removal of
694 // ANSI build and addition of wxUniChar to wxTextOutputStream:
695 s
<< (wxChar
)m_value
;
700 bool wxVariantDataChar::Read(wxInputStream
& str
)
702 wxTextInputStream
s(str
);
704 // FIXME-UTF8: this should be just "s >> m_value;" after removal of
705 // ANSI build and addition of wxUniChar to wxTextInputStream:
712 #endif // wxUSE_STREAMS
714 bool wxVariantDataChar::Read(wxString
& str
)
720 wxVariant::wxVariant(const wxUniChar
& val
, const wxString
& name
)
722 m_data
= new wxVariantDataChar(val
);
726 wxVariant::wxVariant(char val
, const wxString
& name
)
728 m_data
= new wxVariantDataChar(val
);
732 wxVariant::wxVariant(wchar_t val
, const wxString
& name
)
734 m_data
= new wxVariantDataChar(val
);
738 bool wxVariant::operator==(const wxUniChar
& value
) const
741 if (!Convert(&thisValue
))
744 return (value
== thisValue
);
747 wxVariant
& wxVariant::operator=(const wxUniChar
& value
)
749 if (GetType() == wxT("char") &&
750 m_data
->GetRefCount() == 1)
752 ((wxVariantDataChar
*)GetData())->SetValue(value
);
757 m_data
= new wxVariantDataChar(value
);
763 wxUniChar
wxVariant::GetChar() const
766 if (Convert(& value
))
770 wxFAIL_MSG(wxT("Could not convert to a char"));
775 // ----------------------------------------------------------------------------
776 // wxVariantDataString
777 // ----------------------------------------------------------------------------
779 class WXDLLIMPEXP_BASE wxVariantDataString
: public wxVariantData
782 wxVariantDataString() { }
783 wxVariantDataString(const wxString
& value
) { m_value
= value
; }
785 inline wxString
GetValue() const { return m_value
; }
786 inline void SetValue(const wxString
& value
) { m_value
= value
; }
788 virtual bool Eq(wxVariantData
& data
) const;
789 #if wxUSE_STD_IOSTREAM
790 virtual bool Write(wxSTD ostream
& str
) const;
792 virtual bool Read(wxString
& str
);
793 virtual bool Write(wxString
& str
) const;
794 #if wxUSE_STD_IOSTREAM
795 virtual bool Read(wxSTD istream
& WXUNUSED(str
)) { return false; }
798 virtual bool Read(wxInputStream
& str
);
799 virtual bool Write(wxOutputStream
& str
) const;
800 #endif // wxUSE_STREAMS
801 virtual wxString
GetType() const { return wxT("string"); }
807 bool wxVariantDataString::Eq(wxVariantData
& data
) const
809 wxASSERT_MSG( (data
.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
811 wxVariantDataString
& otherData
= (wxVariantDataString
&) data
;
813 return (otherData
.m_value
== m_value
);
816 #if wxUSE_STD_IOSTREAM
817 bool wxVariantDataString::Write(wxSTD ostream
& str
) const
819 str
<< (const char*) m_value
.mb_str();
824 bool wxVariantDataString::Write(wxString
& str
) const
831 bool wxVariantDataString::Write(wxOutputStream
& str
) const
833 // why doesn't wxOutputStream::operator<< take "const wxString&"
834 wxTextOutputStream
s(str
);
835 s
.WriteString(m_value
);
839 bool wxVariantDataString::Read(wxInputStream
& str
)
841 wxTextInputStream
s(str
);
843 m_value
= s
.ReadLine();
846 #endif // wxUSE_STREAMS
848 bool wxVariantDataString::Read(wxString
& str
)
856 wxVariant::wxVariant(const wxString
& val
, const wxString
& name
)
858 m_data
= new wxVariantDataString(val
);
862 wxVariant::wxVariant(const char* val
, const wxString
& name
)
864 m_data
= new wxVariantDataString(wxString(val
));
868 wxVariant::wxVariant(const wchar_t* val
, const wxString
& name
)
870 m_data
= new wxVariantDataString(wxString(val
));
874 wxVariant::wxVariant(const wxCStrData
& val
, const wxString
& name
)
876 m_data
= new wxVariantDataString(val
.AsString());
880 wxVariant::wxVariant(const wxCharBuffer
& val
, const wxString
& name
)
882 m_data
= new wxVariantDataString(wxString(val
));
886 wxVariant::wxVariant(const wxWCharBuffer
& val
, const wxString
& name
)
888 m_data
= new wxVariantDataString(wxString(val
));
892 bool wxVariant::operator== (const wxString
& value
) const
895 if (!Convert(&thisValue
))
898 return value
== thisValue
;
901 bool wxVariant::operator!= (const wxString
& value
) const
903 return (!((*this) == value
));
906 wxVariant
& wxVariant::operator= (const wxString
& value
)
908 if (GetType() == wxT("string") &&
909 m_data
->GetRefCount() == 1)
911 ((wxVariantDataString
*)GetData())->SetValue(value
);
916 m_data
= new wxVariantDataString(value
);
921 wxString
wxVariant::GetString() const
924 if (!Convert(& value
))
926 wxFAIL_MSG(wxT("Could not convert to a string"));
932 // ----------------------------------------------------------------------------
933 // wxVariantDataWxObjectPtr
934 // ----------------------------------------------------------------------------
936 class wxVariantDataWxObjectPtr
: public wxVariantData
939 wxVariantDataWxObjectPtr() { }
940 wxVariantDataWxObjectPtr(wxObject
* value
) { m_value
= value
; }
942 inline wxObject
* GetValue() const { return m_value
; }
943 inline void SetValue(wxObject
* value
) { m_value
= value
; }
945 virtual bool Eq(wxVariantData
& data
) const;
946 #if wxUSE_STD_IOSTREAM
947 virtual bool Write(wxSTD ostream
& str
) const;
949 virtual bool Write(wxString
& str
) const;
950 #if wxUSE_STD_IOSTREAM
951 virtual bool Read(wxSTD istream
& str
);
953 virtual bool Read(wxString
& str
);
954 virtual wxString
GetType() const ;
955 virtual wxVariantData
* Clone() { return new wxVariantDataWxObjectPtr
; }
957 virtual wxClassInfo
* GetValueClassInfo();
963 bool wxVariantDataWxObjectPtr::Eq(wxVariantData
& data
) const
965 wxASSERT_MSG( data
.GetType() == GetType(), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
967 wxVariantDataWxObjectPtr
& otherData
= (wxVariantDataWxObjectPtr
&) data
;
969 return (otherData
.m_value
== m_value
);
972 wxString
wxVariantDataWxObjectPtr::GetType() const
974 wxString
returnVal(wxT("wxObject*"));
978 returnVal
= m_value
->GetClassInfo()->GetClassName();
979 returnVal
+= wxT("*");
985 wxClassInfo
* wxVariantDataWxObjectPtr::GetValueClassInfo()
987 wxClassInfo
* returnVal
=NULL
;
989 if (m_value
) returnVal
= m_value
->GetClassInfo();
994 #if wxUSE_STD_IOSTREAM
995 bool wxVariantDataWxObjectPtr::Write(wxSTD ostream
& str
) const
999 str
<< (const char*) s
.mb_str();
1004 bool wxVariantDataWxObjectPtr::Write(wxString
& str
) const
1006 str
.Printf(wxT("%s(%p)"), GetType().c_str(), wx_static_cast(void*, m_value
));
1010 #if wxUSE_STD_IOSTREAM
1011 bool wxVariantDataWxObjectPtr::Read(wxSTD istream
& WXUNUSED(str
))
1018 bool wxVariantDataWxObjectPtr::Read(wxString
& WXUNUSED(str
))
1026 wxVariant::wxVariant( wxObject
* val
, const wxString
& name
)
1028 m_data
= new wxVariantDataWxObjectPtr(val
);
1032 bool wxVariant::operator== (wxObject
* value
) const
1034 return (value
== ((wxVariantDataWxObjectPtr
*)GetData())->GetValue());
1037 bool wxVariant::operator!= (wxObject
* value
) const
1039 return (!((*this) == (wxObject
*) value
));
1042 void wxVariant::operator= (wxObject
* value
)
1045 m_data
= new wxVariantDataWxObjectPtr(value
);
1048 wxObject
* wxVariant::GetWxObjectPtr() const
1050 return (wxObject
*) ((wxVariantDataWxObjectPtr
*) m_data
)->GetValue();
1053 // ----------------------------------------------------------------------------
1054 // wxVariantDataVoidPtr
1055 // ----------------------------------------------------------------------------
1057 class wxVariantDataVoidPtr
: public wxVariantData
1060 wxVariantDataVoidPtr() { }
1061 wxVariantDataVoidPtr(void* value
) { m_value
= value
; }
1063 inline void* GetValue() const { return m_value
; }
1064 inline void SetValue(void* value
) { m_value
= value
; }
1066 virtual bool Eq(wxVariantData
& data
) const;
1067 #if wxUSE_STD_IOSTREAM
1068 virtual bool Write(wxSTD ostream
& str
) const;
1070 virtual bool Write(wxString
& str
) const;
1071 #if wxUSE_STD_IOSTREAM
1072 virtual bool Read(wxSTD istream
& str
);
1074 virtual bool Read(wxString
& str
);
1075 virtual wxString
GetType() const { return wxT("void*"); }
1076 virtual wxVariantData
* Clone() { return new wxVariantDataVoidPtr
; }
1082 bool wxVariantDataVoidPtr::Eq(wxVariantData
& data
) const
1084 wxASSERT_MSG( data
.GetType() == wxT("void*"), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
1086 wxVariantDataVoidPtr
& otherData
= (wxVariantDataVoidPtr
&) data
;
1088 return (otherData
.m_value
== m_value
);
1091 #if wxUSE_STD_IOSTREAM
1092 bool wxVariantDataVoidPtr::Write(wxSTD ostream
& str
) const
1096 str
<< (const char*) s
.mb_str();
1101 bool wxVariantDataVoidPtr::Write(wxString
& str
) const
1103 str
.Printf(wxT("%p"), m_value
);
1107 #if wxUSE_STD_IOSTREAM
1108 bool wxVariantDataVoidPtr::Read(wxSTD istream
& WXUNUSED(str
))
1115 bool wxVariantDataVoidPtr::Read(wxString
& WXUNUSED(str
))
1123 wxVariant::wxVariant( void* val
, const wxString
& name
)
1125 m_data
= new wxVariantDataVoidPtr(val
);
1129 bool wxVariant::operator== (void* value
) const
1131 return (value
== ((wxVariantDataVoidPtr
*)GetData())->GetValue());
1134 bool wxVariant::operator!= (void* value
) const
1136 return (!((*this) == (void*) value
));
1139 void wxVariant::operator= (void* value
)
1141 if (GetType() == wxT("void*") && (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
1168 wxVariantDataDateTime() { }
1169 wxVariantDataDateTime(const wxDateTime
& value
) { m_value
= value
; }
1171 wxVariantDataDateTime(const TIME_STRUCT
* valptr
)
1172 { m_value
= wxDateTime(valptr
->hour
, valptr
->minute
, valptr
->second
); }
1173 wxVariantDataDateTime(const DATE_STRUCT
* valptr
)
1174 { m_value
= wxDateTime(valptr
->day
, (wxDateTime::Month
) (valptr
->month
- 1),valptr
->year
); }
1175 wxVariantDataDateTime(const TIMESTAMP_STRUCT
* valptr
)
1176 { m_value
= wxDateTime(valptr
->day
, (wxDateTime::Month
) (valptr
->month
- 1), valptr
->year
,
1177 valptr
->hour
, valptr
->minute
, valptr
->second
, (wxDateTime::wxDateTime_t
)valptr
->fraction
); }
1180 inline wxDateTime
GetValue() const { return m_value
; }
1181 inline void SetValue(const wxDateTime
& value
) { m_value
= value
; }
1183 virtual bool Eq(wxVariantData
& data
) const;
1184 #if wxUSE_STD_IOSTREAM
1185 virtual bool Write(wxSTD ostream
& str
) const;
1187 virtual bool Write(wxString
& str
) const;
1188 #if wxUSE_STD_IOSTREAM
1189 virtual bool Read(wxSTD istream
& str
);
1191 virtual bool Read(wxString
& str
);
1192 virtual wxString
GetType() const { return wxT("datetime"); }
1193 virtual wxVariantData
* Clone() { return new wxVariantDataDateTime
; }
1200 bool wxVariantDataDateTime::Eq(wxVariantData
& data
) const
1202 wxASSERT_MSG( (data
.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
1204 wxVariantDataDateTime
& otherData
= (wxVariantDataDateTime
&) data
;
1206 return (otherData
.m_value
== m_value
);
1210 #if wxUSE_STD_IOSTREAM
1211 bool wxVariantDataDateTime::Write(wxSTD ostream
& str
) const
1215 str
<< value
.c_str();
1221 bool wxVariantDataDateTime::Write(wxString
& str
) const
1223 str
= m_value
.Format();
1228 #if wxUSE_STD_IOSTREAM
1229 bool wxVariantDataDateTime::Read(wxSTD istream
& WXUNUSED(str
))
1237 bool wxVariantDataDateTime::Read(wxString
& str
)
1239 if(! m_value
.ParseDateTime(str
.c_str()/*FIXME-UTF8*/))
1246 wxVariant::wxVariant(const wxDateTime
& val
, const wxString
& name
) // Date
1248 m_data
= new wxVariantDataDateTime(val
);
1253 wxVariant::wxVariant(const TIME_STRUCT
* valptr
, const wxString
& name
) // Date
1255 m_data
= new wxVariantDataDateTime(valptr
);
1259 wxVariant::wxVariant(const TIMESTAMP_STRUCT
* valptr
, const wxString
& name
) // Date
1261 m_data
= new wxVariantDataDateTime(valptr
);
1265 wxVariant::wxVariant(const DATE_STRUCT
* valptr
, const wxString
& name
) // Date
1267 m_data
= new wxVariantDataDateTime(valptr
);
1270 #endif // wxUSE_ODBC
1272 bool wxVariant::operator== (const wxDateTime
& value
) const
1274 wxDateTime thisValue
;
1275 if (!Convert(&thisValue
))
1278 return value
.IsEqualTo(thisValue
);
1281 bool wxVariant::operator!= (const wxDateTime
& value
) const
1283 return (!((*this) == value
));
1286 void wxVariant::operator= (const wxDateTime
& value
)
1288 if (GetType() == wxT("datetime") &&
1289 m_data
->GetRefCount() == 1)
1291 ((wxVariantDataDateTime
*)GetData())->SetValue(value
);
1296 m_data
= new wxVariantDataDateTime(value
);
1301 void wxVariant::operator= (const DATE_STRUCT
* value
)
1304 m_data
= new wxVariantDataDateTime(value
);
1307 void wxVariant::operator= (const TIME_STRUCT
* value
)
1310 m_data
= new wxVariantDataDateTime(value
);
1313 void wxVariant::operator= (const TIMESTAMP_STRUCT
* value
)
1316 m_data
= new wxVariantDataDateTime(value
);
1319 #endif // wxUSE_ODBC
1321 wxDateTime
wxVariant::GetDateTime() const
1324 if (!Convert(& value
))
1326 wxFAIL_MSG(wxT("Could not convert to a datetime"));
1332 #endif // wxUSE_DATETIME
1334 // ----------------------------------------------------------------------------
1335 // wxVariantDataArrayString
1336 // ----------------------------------------------------------------------------
1338 class wxVariantDataArrayString
: public wxVariantData
1341 wxVariantDataArrayString() { }
1342 wxVariantDataArrayString(const wxArrayString
& value
) { m_value
= value
; }
1344 wxArrayString
GetValue() const { return m_value
; }
1345 void SetValue(const wxArrayString
& value
) { m_value
= value
; }
1347 virtual bool Eq(wxVariantData
& data
) const;
1348 #if wxUSE_STD_IOSTREAM
1349 virtual bool Write(wxSTD ostream
& str
) const;
1351 virtual bool Write(wxString
& str
) const;
1352 #if wxUSE_STD_IOSTREAM
1353 virtual bool Read(wxSTD istream
& str
);
1355 virtual bool Read(wxString
& str
);
1356 virtual wxString
GetType() const { return wxT("arrstring"); }
1357 virtual wxVariantData
* Clone() { return new wxVariantDataArrayString
; }
1360 wxArrayString m_value
;
1363 bool wxVariantDataArrayString::Eq(wxVariantData
& data
) const
1365 wxASSERT_MSG( data
.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
1367 wxVariantDataArrayString
& otherData
= (wxVariantDataArrayString
&) data
;
1369 return otherData
.m_value
== m_value
;
1372 #if wxUSE_STD_IOSTREAM
1373 bool wxVariantDataArrayString::Write(wxSTD ostream
& WXUNUSED(str
)) const
1380 bool wxVariantDataArrayString::Write(wxString
& str
) const
1382 size_t count
= m_value
.GetCount();
1383 for ( size_t n
= 0; n
< count
; n
++ )
1395 #if wxUSE_STD_IOSTREAM
1396 bool wxVariantDataArrayString::Read(wxSTD istream
& WXUNUSED(str
))
1404 bool wxVariantDataArrayString::Read(wxString
& str
)
1406 wxStringTokenizer
tk(str
, _T(";"));
1407 while ( tk
.HasMoreTokens() )
1409 m_value
.Add(tk
.GetNextToken());
1417 wxVariant::wxVariant(const wxArrayString
& val
, const wxString
& name
) // Strings
1419 m_data
= new wxVariantDataArrayString(val
);
1423 bool wxVariant::operator==(const wxArrayString
& WXUNUSED(value
)) const
1425 wxFAIL_MSG( _T("TODO") );
1430 bool wxVariant::operator!=(const wxArrayString
& value
) const
1432 return !(*this == value
);
1435 void wxVariant::operator=(const wxArrayString
& value
)
1437 if (GetType() == wxT("arrstring") &&
1438 m_data
->GetRefCount() == 1)
1440 ((wxVariantDataArrayString
*)GetData())->SetValue(value
);
1445 m_data
= new wxVariantDataArrayString(value
);
1449 wxArrayString
wxVariant::GetArrayString() const
1451 if ( GetType() == wxT("arrstring") )
1452 return ((wxVariantDataArrayString
*)GetData())->GetValue();
1454 return wxArrayString();
1457 // ----------------------------------------------------------------------------
1458 // wxVariantDataList
1459 // ----------------------------------------------------------------------------
1461 class WXDLLIMPEXP_BASE wxVariantDataList
: public wxVariantData
1464 wxVariantDataList() {}
1465 wxVariantDataList(const wxList
& list
);
1466 virtual ~wxVariantDataList();
1468 wxList
& GetValue() { return m_value
; }
1469 void SetValue(const wxList
& value
) ;
1471 virtual bool Eq(wxVariantData
& data
) const;
1472 #if wxUSE_STD_IOSTREAM
1473 virtual bool Write(wxSTD ostream
& str
) const;
1475 virtual bool Write(wxString
& str
) const;
1476 #if wxUSE_STD_IOSTREAM
1477 virtual bool Read(wxSTD istream
& str
);
1479 virtual bool Read(wxString
& str
);
1480 virtual wxString
GetType() const { return wxT("list"); }
1488 wxVariantDataList::wxVariantDataList(const wxList
& list
)
1493 wxVariantDataList::~wxVariantDataList()
1498 void wxVariantDataList::SetValue(const wxList
& value
)
1501 wxList::compatibility_iterator node
= value
.GetFirst();
1504 wxVariant
* var
= (wxVariant
*) node
->GetData();
1505 m_value
.Append(new wxVariant(*var
));
1506 node
= node
->GetNext();
1510 void wxVariantDataList::Clear()
1512 wxList::compatibility_iterator node
= m_value
.GetFirst();
1515 wxVariant
* var
= (wxVariant
*) node
->GetData();
1517 node
= node
->GetNext();
1522 bool wxVariantDataList::Eq(wxVariantData
& data
) const
1524 wxASSERT_MSG( (data
.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
1526 wxVariantDataList
& listData
= (wxVariantDataList
&) data
;
1527 wxList::compatibility_iterator node1
= m_value
.GetFirst();
1528 wxList::compatibility_iterator node2
= listData
.GetValue().GetFirst();
1529 while (node1
&& node2
)
1531 wxVariant
* var1
= (wxVariant
*) node1
->GetData();
1532 wxVariant
* var2
= (wxVariant
*) node2
->GetData();
1533 if ((*var1
) != (*var2
))
1535 node1
= node1
->GetNext();
1536 node2
= node2
->GetNext();
1538 if (node1
|| node2
) return false;
1542 #if wxUSE_STD_IOSTREAM
1543 bool wxVariantDataList::Write(wxSTD ostream
& str
) const
1547 str
<< (const char*) s
.mb_str();
1552 bool wxVariantDataList::Write(wxString
& str
) const
1554 str
= wxEmptyString
;
1555 wxList::compatibility_iterator node
= m_value
.GetFirst();
1558 wxVariant
* var
= (wxVariant
*) node
->GetData();
1559 if (node
!= m_value
.GetFirst())
1562 str
+= var
->MakeString();
1563 node
= node
->GetNext();
1569 #if wxUSE_STD_IOSTREAM
1570 bool wxVariantDataList::Read(wxSTD istream
& WXUNUSED(str
))
1572 wxFAIL_MSG(wxT("Unimplemented"));
1578 bool wxVariantDataList::Read(wxString
& WXUNUSED(str
))
1580 wxFAIL_MSG(wxT("Unimplemented"));
1587 wxVariant::wxVariant(const wxList
& val
, const wxString
& name
) // List of variants
1589 m_data
= new wxVariantDataList(val
);
1593 bool wxVariant::operator== (const wxList
& value
) const
1595 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1597 wxVariantDataList
other(value
);
1598 return (GetData()->Eq(other
));
1601 bool wxVariant::operator!= (const wxList
& value
) const
1603 return (!((*this) == value
));
1606 void wxVariant::operator= (const wxList
& value
)
1608 if (GetType() == wxT("list") &&
1609 m_data
->GetRefCount() == 1)
1611 ((wxVariantDataList
*)GetData())->SetValue(value
);
1616 m_data
= new wxVariantDataList(value
);
1620 wxList
& wxVariant::GetList() const
1622 wxASSERT( (GetType() == wxT("list")) );
1624 return (wxList
&) ((wxVariantDataList
*) m_data
)->GetValue();
1628 void wxVariant::NullList()
1630 SetData(new wxVariantDataList());
1634 void wxVariant::Append(const wxVariant
& value
)
1636 wxList
& list
= GetList();
1638 list
.Append(new wxVariant(value
));
1641 // Insert at front of list
1642 void wxVariant::Insert(const wxVariant
& value
)
1644 wxList
& list
= GetList();
1646 list
.Insert(new wxVariant(value
));
1649 // Returns true if the variant is a member of the list
1650 bool wxVariant::Member(const wxVariant
& value
) const
1652 wxList
& list
= GetList();
1654 wxList::compatibility_iterator node
= list
.GetFirst();
1657 wxVariant
* other
= (wxVariant
*) node
->GetData();
1658 if (value
== *other
)
1660 node
= node
->GetNext();
1665 // Deletes the nth element of the list
1666 bool wxVariant::Delete(size_t item
)
1668 wxList
& list
= GetList();
1670 wxASSERT_MSG( (item
< list
.GetCount()), wxT("Invalid index to Delete") );
1671 wxList::compatibility_iterator node
= list
.Item(item
);
1672 wxVariant
* variant
= (wxVariant
*) node
->GetData();
1679 void wxVariant::ClearList()
1681 if (!IsNull() && (GetType() == wxT("list")))
1683 ((wxVariantDataList
*) m_data
)->Clear();
1687 if (!GetType().IsSameAs(wxT("list")))
1690 m_data
= new wxVariantDataList
;
1694 // Treat a list variant as an array
1695 wxVariant
wxVariant::operator[] (size_t idx
) const
1697 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
1699 if (GetType() == wxT("list"))
1701 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1702 wxASSERT_MSG( (idx
< data
->GetValue().GetCount()), wxT("Invalid index for array") );
1703 return * (wxVariant
*) (data
->GetValue().Item(idx
)->GetData());
1705 return wxNullVariant
;
1708 wxVariant
& wxVariant::operator[] (size_t idx
)
1710 // We can't return a reference to a variant for a string list, since the string
1711 // is actually stored as a char*, not a variant.
1713 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1715 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1716 wxASSERT_MSG( (idx
< data
->GetValue().GetCount()), wxT("Invalid index for array") );
1718 return * (wxVariant
*) (data
->GetValue().Item(idx
)->GetData());
1721 // Return the number of elements in a list
1722 size_t wxVariant::GetCount() const
1724 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
1726 if (GetType() == wxT("list"))
1728 wxVariantDataList
* data
= (wxVariantDataList
*) m_data
;
1729 return data
->GetValue().GetCount();
1734 // ----------------------------------------------------------------------------
1736 // ----------------------------------------------------------------------------
1738 bool wxVariant::Convert(long* value
) const
1740 wxString
type(GetType());
1741 if (type
== wxT("double"))
1742 *value
= (long) (((wxVariantDoubleData
*)GetData())->GetValue());
1743 else if (type
== wxT("long"))
1744 *value
= ((wxVariantDataLong
*)GetData())->GetValue();
1746 else if (type
== wxT("bool"))
1747 *value
= (long) (((wxVariantDataBool
*)GetData())->GetValue());
1749 else if (type
== wxT("string"))
1750 *value
= wxAtol(((wxVariantDataString
*)GetData())->GetValue());
1757 bool wxVariant::Convert(bool* value
) const
1759 wxString
type(GetType());
1760 if (type
== wxT("double"))
1761 *value
= ((int) (((wxVariantDoubleData
*)GetData())->GetValue()) != 0);
1762 else if (type
== wxT("long"))
1763 *value
= (((wxVariantDataLong
*)GetData())->GetValue() != 0);
1765 else if (type
== wxT("bool"))
1766 *value
= ((wxVariantDataBool
*)GetData())->GetValue();
1768 else if (type
== wxT("string"))
1770 wxString
val(((wxVariantDataString
*)GetData())->GetValue());
1772 if (val
== wxT("true") || val
== wxT("yes") || val
== wxT('1') )
1774 else if (val
== wxT("false") || val
== wxT("no") || val
== wxT('0') )
1785 bool wxVariant::Convert(double* value
) const
1787 wxString
type(GetType());
1788 if (type
== wxT("double"))
1789 *value
= ((wxVariantDoubleData
*)GetData())->GetValue();
1790 else if (type
== wxT("long"))
1791 *value
= (double) (((wxVariantDataLong
*)GetData())->GetValue());
1793 else if (type
== wxT("bool"))
1794 *value
= (double) (((wxVariantDataBool
*)GetData())->GetValue());
1796 else if (type
== wxT("string"))
1797 *value
= (double) wxAtof(((wxVariantDataString
*)GetData())->GetValue());
1804 bool wxVariant::Convert(wxUniChar
* value
) const
1806 wxString
type(GetType());
1807 if (type
== wxT("char"))
1808 *value
= ((wxVariantDataChar
*)GetData())->GetValue();
1809 else if (type
== wxT("long"))
1810 *value
= (char) (((wxVariantDataLong
*)GetData())->GetValue());
1812 else if (type
== wxT("bool"))
1813 *value
= (char) (((wxVariantDataBool
*)GetData())->GetValue());
1821 bool wxVariant::Convert(char* value
) const
1824 if ( !Convert(&ch
) )
1830 bool wxVariant::Convert(wchar_t* value
) const
1833 if ( !Convert(&ch
) )
1839 bool wxVariant::Convert(wxString
* value
) const
1841 *value
= MakeString();
1846 bool wxVariant::Convert(wxDateTime
* value
) const
1848 wxString
type(GetType());
1849 if (type
== wxT("datetime"))
1851 *value
= ((wxVariantDataDateTime
*)GetData())->GetValue();
1854 // Fallback to string conversion
1856 return Convert(&val
) &&
1857 (value
->ParseDateTime(val
.c_str()/*FIXME-UTF8*/) ||
1858 value
->ParseDate(val
.c_str()/*FIXME-UTF8*/) ||
1859 value
->ParseTime(val
.c_str()/*FIXME-UTF8*/));
1861 #endif // wxUSE_DATETIME
1863 #endif // wxUSE_VARIANT