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