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