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