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