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