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