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