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