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