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