]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/variant.cpp
1. use a manifest constant wxNO_LEN instead of -1 for lengths everywhere
[wxWidgets.git] / src / common / variant.cpp
... / ...
CommitLineData
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#if wxUSE_STD_IOSTREAM
20 #if wxUSE_IOSTREAMH
21 #include <fstream.h>
22 #else
23 #include <fstream>
24 #endif
25#endif
26
27#if defined(__MWERKS__) && __MSL__ >= 0x6000
28namespace std {}
29using namespace std ;
30#endif
31
32#if wxUSE_STREAMS
33#include "wx/stream.h"
34#include "wx/txtstrm.h"
35#endif
36
37#include "wx/string.h"
38#include "wx/tokenzr.h"
39#include "wx/math.h"
40
41#include "wx/variant.h"
42
43IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject)
44
45wxVariant WXDLLIMPEXP_BASE wxNullVariant;
46
47/*
48 * wxVariantDataList
49 */
50
51class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
52{
53DECLARE_DYNAMIC_CLASS(wxVariantDataList)
54public:
55 wxVariantDataList() {}
56 wxVariantDataList(const wxList& list);
57 ~wxVariantDataList();
58
59 wxList& GetValue() { return m_value; }
60 void SetValue(const wxList& value) ;
61
62 virtual void Copy(wxVariantData& data);
63 virtual bool Eq(wxVariantData& data) const;
64#if wxUSE_STD_IOSTREAM
65 virtual bool Write(wxSTD ostream& str) const;
66#endif
67 virtual bool Write(wxString& str) const;
68#if wxUSE_STD_IOSTREAM
69 virtual bool Read(wxSTD istream& str);
70#endif
71 virtual bool Read(wxString& str);
72 virtual wxString GetType() const { return wxT("list"); };
73
74 void Clear();
75
76protected:
77 wxList m_value;
78};
79
80IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
81
82wxVariantDataList::wxVariantDataList(const wxList& list)
83{
84 SetValue(list);
85}
86
87wxVariantDataList::~wxVariantDataList()
88{
89 Clear();
90}
91
92void wxVariantDataList::SetValue(const wxList& value)
93{
94 Clear();
95 wxList::compatibility_iterator node = value.GetFirst();
96 while (node)
97 {
98 wxVariant* var = (wxVariant*) node->GetData();
99 m_value.Append(new wxVariant(*var));
100 node = node->GetNext();
101 }
102}
103
104void wxVariantDataList::Clear()
105{
106 wxList::compatibility_iterator node = m_value.GetFirst();
107 while (node)
108 {
109 wxVariant* var = (wxVariant*) node->GetData();
110 delete var;
111 node = node->GetNext();
112 }
113 m_value.Clear();
114}
115
116void wxVariantDataList::Copy(wxVariantData& data)
117{
118 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Copy: Can't copy to this type of data") );
119
120 wxVariantDataList& listData = (wxVariantDataList&) data;
121
122 listData.Clear();
123 wxList::compatibility_iterator node = m_value.GetFirst();
124 while (node)
125 {
126 wxVariant* var = (wxVariant*) node->GetData();
127 listData.m_value.Append(new wxVariant(*var));
128 node = node->GetNext();
129 }
130}
131
132bool wxVariantDataList::Eq(wxVariantData& data) const
133{
134 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
135
136 wxVariantDataList& listData = (wxVariantDataList&) data;
137 wxList::compatibility_iterator node1 = m_value.GetFirst();
138 wxList::compatibility_iterator node2 = listData.GetValue().GetFirst();
139 while (node1 && node2)
140 {
141 wxVariant* var1 = (wxVariant*) node1->GetData();
142 wxVariant* var2 = (wxVariant*) node2->GetData();
143 if ((*var1) != (*var2))
144 return false;
145 node1 = node1->GetNext();
146 node2 = node2->GetNext();
147 }
148 if (node1 || node2) return false;
149 return true;
150}
151
152#if wxUSE_STD_IOSTREAM
153bool wxVariantDataList::Write(wxSTD ostream& str) const
154{
155 wxString s;
156 Write(s);
157 str << (const char*) s.mb_str();
158 return true;
159}
160#endif
161
162bool wxVariantDataList::Write(wxString& str) const
163{
164 str = wxEmptyString;
165 wxList::compatibility_iterator node = m_value.GetFirst();
166 while (node)
167 {
168 wxVariant* var = (wxVariant*) node->GetData();
169 if (node != m_value.GetFirst())
170 str += wxT(" ");
171 wxString str1;
172 str += var->MakeString();
173 node = node->GetNext();
174 }
175
176 return true;
177}
178
179#if wxUSE_STD_IOSTREAM
180bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
181{
182 wxFAIL_MSG(wxT("Unimplemented"));
183 // TODO
184 return false;
185}
186#endif
187
188bool wxVariantDataList::Read(wxString& WXUNUSED(str))
189{
190 wxFAIL_MSG(wxT("Unimplemented"));
191 // TODO
192 return false;
193}
194#if WXWIN_COMPATIBILITY_2_4
195
196/*
197 * wxVariantDataStringList
198 */
199
200class WXDLLIMPEXP_BASE wxVariantDataStringList: public wxVariantData
201{
202DECLARE_DYNAMIC_CLASS(wxVariantDataStringList)
203public:
204 wxVariantDataStringList() {}
205 wxVariantDataStringList(const wxStringList& list) { m_value = list; }
206
207 wxStringList& GetValue() const { return (wxStringList&) m_value; }
208 void SetValue(const wxStringList& value);
209
210 virtual void Copy(wxVariantData& data);
211 virtual bool Eq(wxVariantData& data) const;
212#if wxUSE_STD_IOSTREAM
213 virtual bool Write(wxSTD ostream& str) const;
214#endif
215 virtual bool Write(wxString& str) const;
216#if wxUSE_STD_IOSTREAM
217 virtual bool Read(wxSTD istream& str);
218#endif
219 virtual bool Read(wxString& str);
220 virtual wxString GetType() const { return wxT("stringlist"); };
221
222protected:
223 wxStringList m_value;
224};
225
226IMPLEMENT_DYNAMIC_CLASS(wxVariantDataStringList, wxVariantData)
227
228void wxVariantDataStringList::SetValue(const wxStringList& value)
229{
230 m_value = value;
231}
232
233void wxVariantDataStringList::Copy(wxVariantData& data)
234{
235 wxASSERT_MSG( (data.GetType() == wxT("stringlist")), wxT("wxVariantDataStringList::Copy: Can't copy to this type of data") );
236
237 wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
238
239 listData.m_value = m_value ;
240}
241
242bool wxVariantDataStringList::Eq(wxVariantData& data) const
243{
244 wxASSERT_MSG( (data.GetType() == wxT("stringlist")), wxT("wxVariantDataStringList::Eq: argument mismatch") );
245
246 wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
247 wxStringList::compatibility_iterator node1 = m_value.GetFirst();
248 wxStringList::compatibility_iterator node2 = listData.GetValue().GetFirst();
249 while (node1 && node2)
250 {
251 wxString str1 ( node1->GetData() );
252 wxString str2 ( node2->GetData() );
253 if (str1 != str2)
254 return false;
255 node1 = node1->GetNext();
256 node2 = node2->GetNext();
257 }
258 if (node1 || node2) return false;
259 return true;
260}
261
262#if wxUSE_STD_IOSTREAM
263bool wxVariantDataStringList::Write(wxSTD ostream& str) const
264{
265 wxString s;
266 Write(s);
267 str << (const char*) s.mb_str();
268 return true;
269}
270#endif
271
272bool wxVariantDataStringList::Write(wxString& str) const
273{
274 str.Empty();
275 wxStringList::compatibility_iterator node = m_value.GetFirst();
276 while (node)
277 {
278 const wxChar* s = node->GetData();
279 if (node != m_value.GetFirst())
280 str += wxT(" ");
281 str += s;
282 node = node->GetNext();
283 }
284
285 return true;
286}
287
288#if wxUSE_STD_IOSTREAM
289bool wxVariantDataStringList::Read(wxSTD istream& WXUNUSED(str))
290{
291 wxFAIL_MSG(wxT("Unimplemented"));
292 // TODO
293 return false;
294}
295#endif
296
297bool wxVariantDataStringList::Read(wxString& WXUNUSED(str))
298{
299 wxFAIL_MSG(wxT("Unimplemented"));
300 // TODO
301 return false;
302}
303
304#endif //2.4 compat
305
306/*
307 * wxVariantDataLong
308 */
309
310class WXDLLIMPEXP_BASE wxVariantDataLong: public wxVariantData
311{
312DECLARE_DYNAMIC_CLASS(wxVariantDataLong)
313public:
314 wxVariantDataLong() { m_value = 0; }
315 wxVariantDataLong(long value) { m_value = value; }
316
317 inline long GetValue() const { return m_value; }
318 inline void SetValue(long value) { m_value = value; }
319
320 virtual void Copy(wxVariantData& data);
321 virtual bool Eq(wxVariantData& data) const;
322
323 virtual bool Read(wxString& str);
324 virtual bool Write(wxString& str) const;
325#if wxUSE_STD_IOSTREAM
326 virtual bool Read(wxSTD istream& str);
327 virtual bool Write(wxSTD ostream& str) const;
328#endif
329#if wxUSE_STREAMS
330 virtual bool Read(wxInputStream& str);
331 virtual bool Write(wxOutputStream &str) const;
332#endif // wxUSE_STREAMS
333
334 virtual wxString GetType() const { return wxT("long"); };
335
336protected:
337 long m_value;
338};
339
340IMPLEMENT_DYNAMIC_CLASS(wxVariantDataLong, wxVariantData)
341
342void wxVariantDataLong::Copy(wxVariantData& data)
343{
344 wxASSERT_MSG( (data.GetType() == wxT("long")), wxT("wxVariantDataLong::Copy: Can't copy to this type of data") );
345
346 wxVariantDataLong& otherData = (wxVariantDataLong&) data;
347
348 otherData.m_value = m_value;
349}
350
351bool wxVariantDataLong::Eq(wxVariantData& data) const
352{
353 wxASSERT_MSG( (data.GetType() == wxT("long")), wxT("wxVariantDataLong::Eq: argument mismatch") );
354
355 wxVariantDataLong& otherData = (wxVariantDataLong&) data;
356
357 return (otherData.m_value == m_value);
358}
359
360#if wxUSE_STD_IOSTREAM
361bool wxVariantDataLong::Write(wxSTD ostream& str) const
362{
363 wxString s;
364 Write(s);
365 str << (const char*) s.mb_str();
366 return true;
367}
368#endif
369
370bool wxVariantDataLong::Write(wxString& str) const
371{
372 str.Printf(wxT("%ld"), m_value);
373 return true;
374}
375
376#if wxUSE_STD_IOSTREAM
377bool wxVariantDataLong::Read(wxSTD istream& str)
378{
379 str >> m_value;
380 return true;
381}
382#endif
383
384#if wxUSE_STREAMS
385bool wxVariantDataLong::Write(wxOutputStream& str) const
386{
387 wxTextOutputStream s(str);
388
389 s.Write32((size_t)m_value);
390 return true;
391}
392
393bool wxVariantDataLong::Read(wxInputStream& str)
394{
395 wxTextInputStream s(str);
396 m_value = s.Read32();
397 return true;
398}
399#endif // wxUSE_STREAMS
400
401bool wxVariantDataLong::Read(wxString& str)
402{
403 m_value = wxAtol((const wxChar*) str);
404 return true;
405}
406
407/*
408 * wxVariantDataReal
409 */
410
411class WXDLLIMPEXP_BASE wxVariantDataReal: public wxVariantData
412{
413DECLARE_DYNAMIC_CLASS(wxVariantDataReal)
414public:
415 wxVariantDataReal() { m_value = 0.0; }
416 wxVariantDataReal(double value) { m_value = value; }
417
418 inline double GetValue() const { return m_value; }
419 inline void SetValue(double value) { m_value = value; }
420
421 virtual void Copy(wxVariantData& data);
422 virtual bool Eq(wxVariantData& data) const;
423 virtual bool Read(wxString& str);
424#if wxUSE_STD_IOSTREAM
425 virtual bool Write(wxSTD ostream& str) const;
426#endif
427 virtual bool Write(wxString& str) const;
428#if wxUSE_STD_IOSTREAM
429 virtual bool Read(wxSTD istream& str);
430#endif
431#if wxUSE_STREAMS
432 virtual bool Read(wxInputStream& str);
433 virtual bool Write(wxOutputStream &str) const;
434#endif // wxUSE_STREAMS
435 virtual wxString GetType() const { return wxT("double"); };
436
437protected:
438 double m_value;
439};
440
441IMPLEMENT_DYNAMIC_CLASS(wxVariantDataReal, wxVariantData)
442
443void wxVariantDataReal::Copy(wxVariantData& data)
444{
445 wxASSERT_MSG( (data.GetType() == wxT("double")), wxT("wxVariantDataReal::Copy: Can't copy to this type of data") );
446
447 wxVariantDataReal& otherData = (wxVariantDataReal&) data;
448
449 otherData.m_value = m_value;
450}
451
452bool wxVariantDataReal::Eq(wxVariantData& data) const
453{
454 wxASSERT_MSG( (data.GetType() == wxT("double")), wxT("wxVariantDataReal::Eq: argument mismatch") );
455
456 wxVariantDataReal& otherData = (wxVariantDataReal&) data;
457
458 return wxIsSameDouble(otherData.m_value, m_value);
459}
460
461#if wxUSE_STD_IOSTREAM
462bool wxVariantDataReal::Write(wxSTD ostream& str) const
463{
464 wxString s;
465 Write(s);
466 str << (const char*) s.mb_str();
467 return true;
468}
469#endif
470
471bool wxVariantDataReal::Write(wxString& str) const
472{
473 str.Printf(wxT("%.14g"), m_value);
474 return true;
475}
476
477#if wxUSE_STD_IOSTREAM
478bool wxVariantDataReal::Read(wxSTD istream& str)
479{
480 str >> m_value;
481 return true;
482}
483#endif
484
485#if wxUSE_STREAMS
486bool wxVariantDataReal::Write(wxOutputStream& str) const
487{
488 wxTextOutputStream s(str);
489 s.WriteDouble((double)m_value);
490 return true;
491}
492
493bool wxVariantDataReal::Read(wxInputStream& str)
494{
495 wxTextInputStream s(str);
496 m_value = (float)s.ReadDouble();
497 return true;
498}
499#endif // wxUSE_STREAMS
500
501bool wxVariantDataReal::Read(wxString& str)
502{
503 m_value = wxAtof((const wxChar*) str);
504 return true;
505}
506
507#ifdef HAVE_BOOL
508/*
509 * wxVariantDataBool
510 */
511
512class WXDLLIMPEXP_BASE wxVariantDataBool: public wxVariantData
513{
514DECLARE_DYNAMIC_CLASS(wxVariantDataBool)
515public:
516 wxVariantDataBool() { m_value = 0; }
517 wxVariantDataBool(bool value) { m_value = value; }
518
519 inline bool GetValue() const { return m_value; }
520 inline void SetValue(bool value) { m_value = value; }
521
522 virtual void Copy(wxVariantData& data);
523 virtual bool Eq(wxVariantData& data) const;
524#if wxUSE_STD_IOSTREAM
525 virtual bool Write(wxSTD ostream& str) const;
526#endif
527 virtual bool Write(wxString& str) const;
528 virtual bool Read(wxString& str);
529#if wxUSE_STD_IOSTREAM
530 virtual bool Read(wxSTD istream& str);
531#endif
532#if wxUSE_STREAMS
533 virtual bool Read(wxInputStream& str);
534 virtual bool Write(wxOutputStream& str) const;
535#endif // wxUSE_STREAMS
536 virtual wxString GetType() const { return wxT("bool"); };
537
538protected:
539 bool m_value;
540};
541
542IMPLEMENT_DYNAMIC_CLASS(wxVariantDataBool, wxVariantData)
543
544void wxVariantDataBool::Copy(wxVariantData& data)
545{
546 wxASSERT_MSG( (data.GetType() == wxT("bool")), wxT("wxVariantDataBool::Copy: Can't copy to this type of data") );
547
548 wxVariantDataBool& otherData = (wxVariantDataBool&) data;
549
550 otherData.m_value = m_value;
551}
552
553bool wxVariantDataBool::Eq(wxVariantData& data) const
554{
555 wxASSERT_MSG( (data.GetType() == wxT("bool")), wxT("wxVariantDataBool::Eq: argument mismatch") );
556
557 wxVariantDataBool& otherData = (wxVariantDataBool&) data;
558
559 return (otherData.m_value == m_value);
560}
561
562#if wxUSE_STD_IOSTREAM
563bool wxVariantDataBool::Write(wxSTD ostream& str) const
564{
565 wxString s;
566 Write(s);
567 str << (const char*) s.mb_str();
568 return true;
569}
570#endif
571
572bool wxVariantDataBool::Write(wxString& str) const
573{
574 str.Printf(wxT("%d"), (int) m_value);
575 return true;
576}
577
578#if wxUSE_STD_IOSTREAM
579bool wxVariantDataBool::Read(wxSTD istream& WXUNUSED(str))
580{
581 wxFAIL_MSG(wxT("Unimplemented"));
582// str >> (long) m_value;
583 return false;
584}
585#endif
586
587#if wxUSE_STREAMS
588bool wxVariantDataBool::Write(wxOutputStream& str) const
589{
590 wxTextOutputStream s(str);
591
592 s.Write8(m_value);
593 return true;
594}
595
596bool wxVariantDataBool::Read(wxInputStream& str)
597{
598 wxTextInputStream s(str);
599
600 m_value = s.Read8() != 0;
601 return true;
602}
603#endif // wxUSE_STREAMS
604
605bool wxVariantDataBool::Read(wxString& str)
606{
607 m_value = (wxAtol((const wxChar*) str) != 0);
608 return true;
609}
610#endif // HAVE_BOOL
611
612/*
613 * wxVariantDataChar
614 */
615
616class WXDLLIMPEXP_BASE wxVariantDataChar: public wxVariantData
617{
618DECLARE_DYNAMIC_CLASS(wxVariantDataChar)
619public:
620 wxVariantDataChar() { m_value = 0; }
621 wxVariantDataChar(char value) { m_value = value; }
622
623 inline char GetValue() const { return m_value; }
624 inline void SetValue(char value) { m_value = value; }
625
626 virtual void Copy(wxVariantData& data);
627 virtual bool Eq(wxVariantData& data) const;
628#if wxUSE_STD_IOSTREAM
629 virtual bool Read(wxSTD istream& str);
630 virtual bool Write(wxSTD ostream& str) const;
631#endif
632 virtual bool Read(wxString& str);
633 virtual bool Write(wxString& str) const;
634#if wxUSE_STREAMS
635 virtual bool Read(wxInputStream& str);
636 virtual bool Write(wxOutputStream& str) const;
637#endif // wxUSE_STREAMS
638 virtual wxString GetType() const { return wxT("char"); };
639
640protected:
641 char m_value;
642};
643
644IMPLEMENT_DYNAMIC_CLASS(wxVariantDataChar, wxVariantData)
645
646void wxVariantDataChar::Copy(wxVariantData& data)
647{
648 wxASSERT_MSG( (data.GetType() == wxT("char")), wxT("wxVariantDataChar::Copy: Can't copy to this type of data") );
649
650 wxVariantDataChar& otherData = (wxVariantDataChar&) data;
651
652 otherData.m_value = m_value;
653}
654
655bool wxVariantDataChar::Eq(wxVariantData& data) const
656{
657 wxASSERT_MSG( (data.GetType() == wxT("char")), wxT("wxVariantDataChar::Eq: argument mismatch") );
658
659 wxVariantDataChar& otherData = (wxVariantDataChar&) data;
660
661 return (otherData.m_value == m_value);
662}
663
664#if wxUSE_STD_IOSTREAM
665bool wxVariantDataChar::Write(wxSTD ostream& str) const
666{
667 wxString s;
668 Write(s);
669 str << (const char*) s.mb_str();
670 return true;
671}
672#endif
673
674bool wxVariantDataChar::Write(wxString& str) const
675{
676 str.Printf(wxT("%c"), m_value);
677 return true;
678}
679
680#if wxUSE_STD_IOSTREAM
681bool wxVariantDataChar::Read(wxSTD istream& WXUNUSED(str))
682{
683 wxFAIL_MSG(wxT("Unimplemented"));
684// str >> m_value;
685 return false;
686}
687#endif
688
689#if wxUSE_STREAMS
690bool wxVariantDataChar::Write(wxOutputStream& str) const
691{
692 wxTextOutputStream s(str);
693
694 s.Write8(m_value);
695 return true;
696}
697
698bool wxVariantDataChar::Read(wxInputStream& str)
699{
700 wxTextInputStream s(str);
701
702 m_value = s.Read8();
703 return true;
704}
705#endif // wxUSE_STREAMS
706
707bool wxVariantDataChar::Read(wxString& str)
708{
709 m_value = str.ToAscii()[size_t(0)];
710 return true;
711}
712
713/*
714 * wxVariantDataString
715 */
716
717class WXDLLIMPEXP_BASE wxVariantDataString: public wxVariantData
718{
719DECLARE_DYNAMIC_CLASS(wxVariantDataString)
720public:
721 wxVariantDataString() { }
722 wxVariantDataString(const wxString& value) { m_value = value; }
723
724 inline wxString GetValue() const { return m_value; }
725 inline void SetValue(const wxString& value) { m_value = value; }
726
727 virtual void Copy(wxVariantData& data);
728 virtual bool Eq(wxVariantData& data) const;
729#if wxUSE_STD_IOSTREAM
730 virtual bool Write(wxSTD ostream& str) const;
731#endif
732 virtual bool Read(wxString& str);
733 virtual bool Write(wxString& str) const;
734#if wxUSE_STD_IOSTREAM
735 virtual bool Read(wxSTD istream& str);
736#endif
737#if wxUSE_STREAMS
738 virtual bool Read(wxInputStream& str);
739 virtual bool Write(wxOutputStream& str) const;
740#endif // wxUSE_STREAMS
741 virtual wxString GetType() const { return wxT("string"); };
742
743protected:
744 wxString m_value;
745};
746
747void wxVariantDataString::Copy(wxVariantData& data)
748{
749 wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Copy: Can't copy to this type of data") );
750
751 wxVariantDataString& otherData = (wxVariantDataString&) data;
752
753 otherData.m_value = m_value;
754}
755
756bool wxVariantDataString::Eq(wxVariantData& data) const
757{
758 wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
759
760 wxVariantDataString& otherData = (wxVariantDataString&) data;
761
762 return (otherData.m_value == m_value);
763}
764
765#if wxUSE_STD_IOSTREAM
766bool wxVariantDataString::Write(wxSTD ostream& str) const
767{
768 str << (const char*) m_value.mb_str();
769 return true;
770}
771#endif
772
773bool wxVariantDataString::Write(wxString& str) const
774{
775 str = m_value;
776 return true;
777}
778
779#if wxUSE_STD_IOSTREAM
780bool wxVariantDataString::Read(wxSTD istream& str)
781{
782 str >> m_value;
783 return true;
784}
785#endif
786
787#if wxUSE_STREAMS
788bool wxVariantDataString::Write(wxOutputStream& str) const
789{
790 // why doesn't wxOutputStream::operator<< take "const wxString&"
791 wxTextOutputStream s(str);
792 s.WriteString(m_value);
793 return true;
794}
795
796bool wxVariantDataString::Read(wxInputStream& str)
797{
798 wxTextInputStream s(str);
799
800 m_value = s.ReadString();
801 return true;
802}
803#endif // wxUSE_STREAMS
804
805bool wxVariantDataString::Read(wxString& str)
806{
807 m_value = str;
808 return true;
809}
810
811IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
812
813/*
814 * wxVariantDataVoidPtr
815 */
816
817class wxVariantDataVoidPtr: public wxVariantData
818{
819DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
820public:
821 wxVariantDataVoidPtr() { }
822 wxVariantDataVoidPtr(void* value) { m_value = value; }
823
824 inline void* GetValue() const { return m_value; }
825 inline void SetValue(void* value) { m_value = value; }
826
827 virtual void Copy(wxVariantData& data);
828 virtual bool Eq(wxVariantData& data) const;
829#if wxUSE_STD_IOSTREAM
830 virtual bool Write(wxSTD ostream& str) const;
831#endif
832 virtual bool Write(wxString& str) const;
833#if wxUSE_STD_IOSTREAM
834 virtual bool Read(wxSTD istream& str);
835#endif
836 virtual bool Read(wxString& str);
837 virtual wxString GetType() const { return wxT("void*"); };
838 virtual wxVariantData* Clone() { return new wxVariantDataVoidPtr; }
839
840protected:
841 void* m_value;
842
843 DECLARE_NO_COPY_CLASS(wxVariantDataVoidPtr)
844};
845
846IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
847
848void wxVariantDataVoidPtr::Copy(wxVariantData& data)
849{
850 wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Copy: Can't copy to this type of data") );
851
852 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
853
854 otherData.m_value = m_value;
855}
856
857bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
858{
859 wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
860
861 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
862
863 return (otherData.m_value == m_value);
864}
865
866#if wxUSE_STD_IOSTREAM
867bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
868{
869 wxString s;
870 Write(s);
871 str << (const char*) s.mb_str();
872 return true;
873}
874#endif
875
876bool wxVariantDataVoidPtr::Write(wxString& str) const
877{
878 str.Printf(wxT("%p"), m_value);
879 return true;
880}
881
882#if wxUSE_STD_IOSTREAM
883bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
884{
885 // Not implemented
886 return false;
887}
888#endif
889
890bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
891{
892 // Not implemented
893 return false;
894}
895
896/*
897 * wxVariantDataWxObjectPtr
898 */
899
900class wxVariantDataWxObjectPtr: public wxVariantData
901{
902DECLARE_DYNAMIC_CLASS(wxVariantDataWxObjectPtr)
903public:
904 wxVariantDataWxObjectPtr() { }
905 wxVariantDataWxObjectPtr(wxObject* value) { m_value = value; }
906
907 inline wxObject* GetValue() const { return m_value; }
908 inline void SetValue(wxObject* value) { m_value = value; }
909
910 virtual void Copy(wxVariantData& data);
911 virtual bool Eq(wxVariantData& data) const;
912#if wxUSE_STD_IOSTREAM
913 virtual bool Write(wxSTD ostream& str) const;
914#endif
915 virtual bool Write(wxString& str) const;
916#if wxUSE_STD_IOSTREAM
917 virtual bool Read(wxSTD istream& str);
918#endif
919 virtual bool Read(wxString& str);
920 virtual wxString GetType() const ;
921 virtual wxVariantData* Clone() { return new wxVariantDataWxObjectPtr; }
922
923 virtual wxClassInfo* GetValueClassInfo() ;
924protected:
925 wxObject* m_value;
926
927 DECLARE_NO_COPY_CLASS(wxVariantDataWxObjectPtr)
928};
929
930IMPLEMENT_DYNAMIC_CLASS(wxVariantDataWxObjectPtr, wxVariantData)
931
932void wxVariantDataWxObjectPtr::Copy(wxVariantData& data)
933{
934 wxASSERT_MSG( wxIsKindOf((&data), wxVariantDataWxObjectPtr) ,\
935 wxT("wxVariantDataWxObjectPtr::Copy: Can't copy to this type of data") \
936 );
937
938 wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
939
940 otherData.m_value = m_value;
941}
942
943bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const
944{
945 wxASSERT_MSG( wxIsKindOf((&data), wxVariantDataWxObjectPtr), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
946
947 wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
948
949 return (otherData.m_value == m_value);
950}
951
952wxString wxVariantDataWxObjectPtr::GetType() const
953{
954 wxString returnVal(wxT("wxObject"));
955 if (m_value) {
956 returnVal = m_value->GetClassInfo()->GetClassName();
957 }
958 return returnVal;
959}
960
961wxClassInfo* wxVariantDataWxObjectPtr::GetValueClassInfo()
962{
963 wxClassInfo* returnVal=NULL;
964
965 if (m_value) returnVal = m_value->GetClassInfo();
966
967 return returnVal;
968}
969
970#if wxUSE_STD_IOSTREAM
971bool wxVariantDataWxObjectPtr::Write(wxSTD ostream& str) const
972{
973 wxString s;
974 Write(s);
975 str << (const char*) s.mb_str();
976 return true;
977}
978#endif
979
980bool wxVariantDataWxObjectPtr::Write(wxString& str) const
981{
982 str.Printf(wxT("%s(%p)"), GetType().c_str(), m_value);
983 return true;
984}
985
986#if wxUSE_STD_IOSTREAM
987bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
988{
989 // Not implemented
990 return false;
991}
992#endif
993
994bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
995{
996 // Not implemented
997 return false;
998}
999
1000
1001/*
1002 * wxVariantDataDateTime
1003 */
1004
1005#if wxUSE_DATETIME
1006
1007class wxVariantDataDateTime: public wxVariantData
1008{
1009 DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime)
1010
1011public:
1012 wxVariantDataDateTime() { }
1013 wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
1014#if wxUSE_ODBC
1015 wxVariantDataDateTime(const TIME_STRUCT* valptr)
1016 { m_value = wxDateTime(valptr->hour, valptr->minute, valptr->second); }
1017 wxVariantDataDateTime(const DATE_STRUCT* valptr)
1018 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1),valptr->year); }
1019 wxVariantDataDateTime(const TIMESTAMP_STRUCT* valptr)
1020 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1), valptr->year,
1021 valptr->hour, valptr->minute, valptr->second, (wxDateTime::wxDateTime_t)valptr->fraction ); }
1022#endif //ODBC
1023
1024 inline wxDateTime GetValue() const { return m_value; }
1025 inline void SetValue(const wxDateTime& value) { m_value = value; }
1026
1027 virtual void Copy(wxVariantData& data);
1028 virtual bool Eq(wxVariantData& data) const;
1029#if wxUSE_STD_IOSTREAM
1030 virtual bool Write(wxSTD ostream& str) const;
1031#endif
1032 virtual bool Write(wxString& str) const;
1033#if wxUSE_STD_IOSTREAM
1034 virtual bool Read(wxSTD istream& str);
1035#endif
1036 virtual bool Read(wxString& str);
1037 virtual wxString GetType() const { return wxT("datetime"); };
1038 virtual wxVariantData* Clone() { return new wxVariantDataDateTime; }
1039
1040protected:
1041 wxDateTime m_value;
1042};
1043
1044
1045IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime, wxVariantData)
1046
1047void wxVariantDataDateTime::Copy(wxVariantData& data)
1048{
1049 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Copy: Can't copy to this type of data") );
1050
1051 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1052
1053 otherData.m_value = m_value;
1054}
1055
1056
1057bool wxVariantDataDateTime::Eq(wxVariantData& data) const
1058{
1059 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
1060
1061 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1062
1063 return (otherData.m_value == m_value);
1064}
1065
1066
1067#if wxUSE_STD_IOSTREAM
1068bool wxVariantDataDateTime::Write(wxSTD ostream& WXUNUSED(str)) const
1069{
1070 // Not implemented
1071 return false;
1072}
1073#endif
1074
1075
1076bool wxVariantDataDateTime::Write(wxString& str) const
1077{
1078 str = m_value.Format();
1079 return true;
1080}
1081
1082
1083#if wxUSE_STD_IOSTREAM
1084bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
1085{
1086 // Not implemented
1087 return false;
1088}
1089#endif
1090
1091
1092bool wxVariantDataDateTime::Read(wxString& str)
1093{
1094 if(! m_value.ParseDateTime(str))
1095 return false;
1096 return true;
1097}
1098
1099#endif // wxUSE_DATETIME
1100
1101// ----------------------------------------------------------------------------
1102// wxVariantDataArrayString
1103// ----------------------------------------------------------------------------
1104
1105class wxVariantDataArrayString: public wxVariantData
1106{
1107public:
1108 wxVariantDataArrayString() { }
1109 wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
1110
1111 wxArrayString GetValue() const { return m_value; }
1112 void SetValue(const wxArrayString& value) { m_value = value; }
1113
1114 virtual void Copy(wxVariantData& data);
1115 virtual bool Eq(wxVariantData& data) const;
1116#if wxUSE_STD_IOSTREAM
1117 virtual bool Write(wxSTD ostream& str) const;
1118#endif
1119 virtual bool Write(wxString& str) const;
1120#if wxUSE_STD_IOSTREAM
1121 virtual bool Read(wxSTD istream& str);
1122#endif
1123 virtual bool Read(wxString& str);
1124 virtual wxString GetType() const { return wxT("arrstring"); };
1125 virtual wxVariantData* Clone() { return new wxVariantDataArrayString; }
1126
1127protected:
1128 wxArrayString m_value;
1129
1130 DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString)
1131};
1132
1133IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString, wxVariantData)
1134
1135void wxVariantDataArrayString::Copy(wxVariantData& data)
1136{
1137 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Copy: Can't copy to this type of data") );
1138
1139 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
1140
1141 otherData.m_value = m_value;
1142}
1143
1144
1145bool wxVariantDataArrayString::Eq(wxVariantData& data) const
1146{
1147 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
1148
1149 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
1150
1151 return otherData.m_value == m_value;
1152}
1153
1154
1155#if wxUSE_STD_IOSTREAM
1156bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
1157{
1158 // Not implemented
1159 return false;
1160}
1161#endif
1162
1163
1164bool wxVariantDataArrayString::Write(wxString& str) const
1165{
1166 size_t count = m_value.GetCount();
1167 for ( size_t n = 0; n < count; n++ )
1168 {
1169 if ( n )
1170 str += _T(';');
1171
1172 str += m_value[n];
1173 }
1174
1175 return true;
1176}
1177
1178
1179#if wxUSE_STD_IOSTREAM
1180bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
1181{
1182 // Not implemented
1183 return false;
1184}
1185#endif
1186
1187
1188bool wxVariantDataArrayString::Read(wxString& str)
1189{
1190 wxStringTokenizer tk(str, _T(";"));
1191 while ( tk.HasMoreTokens() )
1192 {
1193 m_value.Add(tk.GetNextToken());
1194 }
1195
1196 return true;
1197}
1198
1199
1200
1201/*
1202 * wxVariant
1203 */
1204
1205IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
1206
1207// Construction & destruction
1208wxVariant::wxVariant()
1209{
1210 m_data = (wxVariantData*) NULL;
1211}
1212
1213wxVariant::wxVariant(double val, const wxString& name)
1214{
1215 m_data = new wxVariantDataReal(val);
1216 m_name = name;
1217}
1218
1219wxVariant::wxVariant(long val, const wxString& name)
1220{
1221 m_data = new wxVariantDataLong(val);
1222 m_name = name;
1223}
1224
1225#ifdef HAVE_BOOL
1226wxVariant::wxVariant(bool val, const wxString& name)
1227{
1228 m_data = new wxVariantDataBool(val);
1229 m_name = name;
1230}
1231#endif
1232
1233wxVariant::wxVariant(char val, const wxString& name)
1234{
1235 m_data = new wxVariantDataChar(val);
1236 m_name = name;
1237}
1238
1239wxVariant::wxVariant(const wxString& val, const wxString& name)
1240{
1241 m_data = new wxVariantDataString(val);
1242 m_name = name;
1243}
1244
1245wxVariant::wxVariant(const wxChar* val, const wxString& name)
1246{
1247 m_data = new wxVariantDataString(wxString(val));
1248 m_name = name;
1249}
1250
1251#if WXWIN_COMPATIBILITY_2_4
1252
1253wxVariant::wxVariant(const wxStringList& val, const wxString& name)
1254{
1255 m_data = new wxVariantDataStringList(val);
1256 m_name = name;
1257}
1258
1259#endif
1260
1261wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
1262{
1263 m_data = new wxVariantDataList(val);
1264 m_name = name;
1265}
1266
1267wxVariant::wxVariant( void* val, const wxString& name)
1268{
1269 m_data = new wxVariantDataVoidPtr(val);
1270 m_name = name;
1271}
1272
1273wxVariant::wxVariant( wxObject* val, const wxString& name)
1274{
1275 m_data = new wxVariantDataWxObjectPtr(val);
1276 m_name = name;
1277}
1278
1279#if wxUSE_DATETIME
1280wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1281{
1282 m_data = new wxVariantDataDateTime(val);
1283 m_name = name;
1284}
1285#endif // wxUSE_DATETIME
1286
1287#if wxUSE_ODBC
1288wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1289{
1290 m_data = new wxVariantDataDateTime(valptr);
1291 m_name = name;
1292}
1293
1294wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1295{
1296 m_data = new wxVariantDataDateTime(valptr);
1297 m_name = name;
1298}
1299
1300wxVariant::wxVariant(const DATE_STRUCT* valptr, const wxString& name) // Date
1301{
1302 m_data = new wxVariantDataDateTime(valptr);
1303 m_name = name;
1304}
1305#endif // wxUSE_ODBC
1306
1307wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1308{
1309 m_data = new wxVariantDataArrayString(val);
1310 m_name = name;
1311}
1312
1313wxVariant::wxVariant(const wxVariant& variant)
1314 : wxObject()
1315{
1316 if (!variant.IsNull())
1317 {
1318 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1319 variant.m_data->Copy(*m_data);
1320 }
1321 else
1322 m_data = (wxVariantData*) NULL;
1323 m_name = variant.m_name;
1324}
1325
1326wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
1327{
1328 m_data = data;
1329 m_name = name;
1330}
1331
1332wxVariant::~wxVariant()
1333{
1334 delete m_data;
1335}
1336
1337
1338// Make NULL (i.e. delete the data)
1339void wxVariant::MakeNull()
1340{
1341 delete m_data;
1342 m_data = NULL;
1343}
1344
1345// Generic operators
1346// Assignment
1347void wxVariant::operator= (const wxVariant& variant)
1348{
1349 if (variant.IsNull())
1350 {
1351 MakeNull();
1352 return;
1353 }
1354
1355 if (IsNull() || (GetType() != variant.GetType()))
1356 {
1357 if (m_data)
1358 delete m_data;
1359 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1360 }
1361
1362 variant.GetData()->Copy(* GetData());
1363
1364 m_name = variant.m_name;
1365}
1366
1367// Assignment using data, e.g.
1368// myVariant = new wxStringVariantData("hello")
1369void wxVariant::operator= (wxVariantData* variantData)
1370{
1371 MakeNull();
1372 m_data = variantData;
1373}
1374
1375bool wxVariant::operator== (const wxVariant& variant) const
1376{
1377 if (IsNull() || variant.IsNull())
1378 return (IsNull() == variant.IsNull());
1379
1380 return (GetData()->Eq(* variant.GetData()));
1381}
1382
1383bool wxVariant::operator!= (const wxVariant& variant) const
1384{
1385 return (!(*this == variant));
1386}
1387
1388
1389// Specific operators
1390bool wxVariant::operator== (double value) const
1391{
1392 double thisValue;
1393 if (!Convert(&thisValue))
1394 return false;
1395
1396 return wxIsSameDouble(value, thisValue);
1397}
1398
1399bool wxVariant::operator!= (double value) const
1400{
1401 return (!((*this) == value));
1402}
1403
1404void wxVariant::operator= (double value)
1405{
1406 if (GetType() == wxT("double"))
1407 {
1408 ((wxVariantDataReal*)GetData())->SetValue(value);
1409 }
1410 else
1411 {
1412 if (m_data)
1413 delete m_data;
1414 m_data = new wxVariantDataReal(value);
1415 }
1416}
1417
1418bool wxVariant::operator== (long value) const
1419{
1420 long thisValue;
1421 if (!Convert(&thisValue))
1422 return false;
1423 else
1424 return (value == thisValue);
1425}
1426
1427bool wxVariant::operator!= (long value) const
1428{
1429 return (!((*this) == value));
1430}
1431
1432void wxVariant::operator= (long value)
1433{
1434 if (GetType() == wxT("long"))
1435 {
1436 ((wxVariantDataLong*)GetData())->SetValue(value);
1437 }
1438 else
1439 {
1440 if (m_data)
1441 delete m_data;
1442 m_data = new wxVariantDataLong(value);
1443 }
1444}
1445
1446bool wxVariant::operator== (char value) const
1447{
1448 char thisValue;
1449 if (!Convert(&thisValue))
1450 return false;
1451 else
1452 return (value == thisValue);
1453}
1454
1455bool wxVariant::operator!= (char value) const
1456{
1457 return (!((*this) == value));
1458}
1459
1460void wxVariant::operator= (char value)
1461{
1462 if (GetType() == wxT("char"))
1463 {
1464 ((wxVariantDataChar*)GetData())->SetValue(value);
1465 }
1466 else
1467 {
1468 if (m_data)
1469 delete m_data;
1470 m_data = new wxVariantDataChar(value);
1471 }
1472}
1473
1474#ifdef HAVE_BOOL
1475bool wxVariant::operator== (bool value) const
1476{
1477 bool thisValue;
1478 if (!Convert(&thisValue))
1479 return false;
1480 else
1481 return (value == thisValue);
1482}
1483
1484bool wxVariant::operator!= (bool value) const
1485{
1486 return (!((*this) == value));
1487}
1488
1489void wxVariant::operator= (bool value)
1490{
1491 if (GetType() == wxT("bool"))
1492 {
1493 ((wxVariantDataBool*)GetData())->SetValue(value);
1494 }
1495 else
1496 {
1497 if (m_data)
1498 delete m_data;
1499 m_data = new wxVariantDataBool(value);
1500 }
1501}
1502#endif // HAVE_BOOL
1503
1504bool wxVariant::operator== (const wxString& value) const
1505{
1506 wxString thisValue;
1507 if (!Convert(&thisValue))
1508 return false;
1509
1510 return value == thisValue;
1511}
1512
1513bool wxVariant::operator!= (const wxString& value) const
1514{
1515 return (!((*this) == value));
1516}
1517
1518void wxVariant::operator= (const wxString& value)
1519{
1520 if (GetType() == wxT("string"))
1521 {
1522 ((wxVariantDataString*)GetData())->SetValue(value);
1523 }
1524 else
1525 {
1526 if (m_data)
1527 delete m_data;
1528 m_data = new wxVariantDataString(value);
1529 }
1530}
1531
1532void wxVariant::operator= (const wxChar* value)
1533{
1534 if (GetType() == wxT("string"))
1535 {
1536 ((wxVariantDataString*)GetData())->SetValue(wxString(value));
1537 }
1538 else
1539 {
1540 if (m_data)
1541 delete m_data;
1542 m_data = new wxVariantDataString(wxString(value));
1543 }
1544}
1545
1546#if WXWIN_COMPATIBILITY_2_4
1547
1548bool wxVariant::operator== (const wxStringList& value) const
1549{
1550 wxASSERT_MSG( (GetType() == wxT("stringlist")), wxT("Invalid type for == operator") );
1551
1552 wxVariantDataStringList other(value);
1553 return (m_data->Eq(other));
1554}
1555
1556bool wxVariant::operator!= (const wxStringList& value) const
1557{
1558 wxASSERT_MSG( (GetType() == wxT("stringlist")), wxT("Invalid type for == operator") );
1559
1560 wxVariantDataStringList other(value);
1561 return !(m_data->Eq(other));
1562}
1563
1564void wxVariant::operator= (const wxStringList& value)
1565{
1566 if (GetType() == wxT("stringlist"))
1567 {
1568 ((wxVariantDataStringList*)GetData())->SetValue(value);
1569 }
1570 else
1571 {
1572 if (m_data)
1573 delete m_data;
1574 m_data = new wxVariantDataStringList(value);
1575 }
1576}
1577
1578#endif
1579
1580bool wxVariant::operator== (const wxList& value) const
1581{
1582 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1583
1584 wxVariantDataList other(value);
1585 return (m_data->Eq(other));
1586}
1587
1588bool wxVariant::operator!= (const wxList& value) const
1589{
1590 return (!((*this) == value));
1591}
1592
1593void wxVariant::operator= (const wxList& value)
1594{
1595 if (GetType() == wxT("list"))
1596 {
1597 ((wxVariantDataList*)GetData())->SetValue(value);
1598 }
1599 else
1600 {
1601 if (m_data)
1602 delete m_data;
1603 m_data = new wxVariantDataList(value);
1604 }
1605}
1606
1607bool wxVariant::operator== (void* value) const
1608{
1609 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
1610}
1611
1612bool wxVariant::operator!= (void* value) const
1613{
1614 return (!((*this) == (void*) value));
1615}
1616
1617void wxVariant::operator= (void* value)
1618{
1619 if (GetType() == wxT("void*"))
1620 {
1621 ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1622 }
1623 else
1624 {
1625 if (m_data)
1626 delete m_data;
1627 m_data = new wxVariantDataVoidPtr(value);
1628 }
1629}
1630
1631#if wxUSE_DATETIME
1632bool wxVariant::operator== (const wxDateTime& value) const
1633{
1634 wxDateTime thisValue;
1635 if (!Convert(&thisValue))
1636 return false;
1637
1638 return value.IsEqualTo(thisValue);
1639}
1640
1641bool wxVariant::operator!= (const wxDateTime& value) const
1642{
1643 return (!((*this) == value));
1644}
1645
1646void wxVariant::operator= (const wxDateTime& value)
1647{
1648 if (GetType() == wxT("datetime"))
1649 {
1650 ((wxVariantDataDateTime*)GetData())->SetValue(value);
1651 }
1652 else
1653 {
1654 if (m_data)
1655 delete m_data;
1656 m_data = new wxVariantDataDateTime(value);
1657 }
1658}
1659#endif // wxUSE_DATETIME
1660
1661#if wxUSE_ODBC
1662void wxVariant::operator= (const DATE_STRUCT* value)
1663{
1664 if (m_data)
1665 delete m_data;
1666 m_data = new wxVariantDataDateTime(value);
1667}
1668
1669
1670void wxVariant::operator= (const TIME_STRUCT* value)
1671{
1672 if (m_data)
1673 delete m_data;
1674 m_data = new wxVariantDataDateTime(value);
1675}
1676
1677
1678void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
1679{
1680 if (m_data)
1681 delete m_data;
1682 m_data = new wxVariantDataDateTime(value);
1683}
1684
1685#endif // wxUSE_ODBC
1686
1687bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
1688{
1689 wxFAIL_MSG( _T("TODO") );
1690
1691 return false;
1692}
1693
1694bool wxVariant::operator!=(const wxArrayString& value) const
1695{
1696 return !(*this == value);
1697}
1698
1699void wxVariant::operator=(const wxArrayString& value)
1700{
1701 if (GetType() == wxT("arrstring"))
1702 {
1703 ((wxVariantDataArrayString *)GetData())->SetValue(value);
1704 }
1705 else
1706 {
1707 delete m_data;
1708 m_data = new wxVariantDataArrayString(value);
1709 }
1710}
1711
1712wxArrayString wxVariant::GetArrayString() const
1713{
1714 if ( GetType() == wxT("arrstring") )
1715 return ((wxVariantDataArrayString *)GetData())->GetValue();
1716
1717 return wxArrayString();
1718}
1719
1720
1721// Treat a list variant as an array
1722wxVariant wxVariant::operator[] (size_t idx) const
1723{
1724#if WXWIN_COMPATIBILITY_2_4
1725 wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for array operator") );
1726#else
1727 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
1728#endif
1729
1730 if (GetType() == wxT("list"))
1731 {
1732 wxVariantDataList* data = (wxVariantDataList*) m_data;
1733 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1734 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1735 }
1736#if WXWIN_COMPATIBILITY_2_4
1737 else if (GetType() == wxT("stringlist"))
1738 {
1739 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1740 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1741
1742 wxString str( (const wxChar*) (data->GetValue().Item(idx)->GetData()) );
1743 wxVariant variant( str );
1744 return variant;
1745 }
1746#endif
1747 return wxNullVariant;
1748}
1749
1750wxVariant& wxVariant::operator[] (size_t idx)
1751{
1752 // We can't return a reference to a variant for a string list, since the string
1753 // is actually stored as a char*, not a variant.
1754
1755 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1756
1757 wxVariantDataList* data = (wxVariantDataList*) m_data;
1758 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1759
1760 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1761}
1762
1763// Return the number of elements in a list
1764size_t wxVariant::GetCount() const
1765{
1766#if WXWIN_COMPATIBILITY_2_4
1767 wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for GetCount()") );
1768#else
1769 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
1770#endif
1771
1772 if (GetType() == wxT("list"))
1773 {
1774 wxVariantDataList* data = (wxVariantDataList*) m_data;
1775 return data->GetValue().GetCount();
1776 }
1777#if WXWIN_COMPATIBILITY_2_4
1778 else if (GetType() == wxT("stringlist"))
1779 {
1780 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1781 return data->GetValue().GetCount();
1782 }
1783#endif
1784 return 0;
1785}
1786
1787wxString wxVariant::MakeString() const
1788{
1789 if (!IsNull())
1790 {
1791 wxString str;
1792 if (GetData()->Write(str))
1793 return str;
1794 }
1795 return wxEmptyString;
1796}
1797
1798// Accessors
1799
1800void wxVariant::SetData(wxVariantData* data)
1801{
1802 if (m_data) delete m_data;
1803 m_data = data;
1804}
1805
1806
1807// Returns a string representing the type of the variant,
1808// e.g. "string", "bool", "list", "double", "long"
1809wxString wxVariant::GetType() const
1810{
1811 if (IsNull())
1812 return wxString(wxT("null"));
1813 else
1814 return m_data->GetType();
1815}
1816
1817
1818bool wxVariant::IsType(const wxString& type) const
1819{
1820 return (GetType() == type);
1821}
1822
1823bool wxVariant::IsValueKindOf(const wxClassInfo* type) const
1824{
1825 wxClassInfo* info=m_data->GetValueClassInfo();
1826 return info ? info->IsKindOf(type) : false ;
1827}
1828
1829
1830// Value accessors
1831double wxVariant::GetReal() const
1832{
1833 double value;
1834 if (Convert(& value))
1835 return value;
1836 else
1837 {
1838 wxFAIL_MSG(wxT("Could not convert to a real number"));
1839 return 0.0;
1840 }
1841}
1842
1843long wxVariant::GetInteger() const
1844{
1845 long value;
1846 if (Convert(& value))
1847 return value;
1848 else
1849 {
1850 wxFAIL_MSG(wxT("Could not convert to an integer"));
1851 return 0;
1852 }
1853}
1854
1855char wxVariant::GetChar() const
1856{
1857 char value;
1858 if (Convert(& value))
1859 return value;
1860 else
1861 {
1862 wxFAIL_MSG(wxT("Could not convert to a char"));
1863 return 0;
1864 }
1865}
1866
1867bool wxVariant::GetBool() const
1868{
1869 bool value;
1870 if (Convert(& value))
1871 return value;
1872 else
1873 {
1874 wxFAIL_MSG(wxT("Could not convert to a bool"));
1875 return 0;
1876 }
1877}
1878
1879wxString wxVariant::GetString() const
1880{
1881 wxString value;
1882 if (!Convert(& value))
1883 {
1884 wxFAIL_MSG(wxT("Could not convert to a string"));
1885 }
1886
1887 return value;
1888}
1889
1890void* wxVariant::GetVoidPtr() const
1891{
1892 wxASSERT( (GetType() == wxT("void*")) );
1893
1894 return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
1895}
1896
1897wxObject* wxVariant::GetWxObjectPtr()
1898{
1899 wxASSERT(wxIsKindOf(m_data, wxVariantDataWxObjectPtr));
1900 return (wxObject*) ((wxVariantDataWxObjectPtr*) m_data)->GetValue();
1901}
1902
1903#if wxUSE_DATETIME
1904wxDateTime wxVariant::GetDateTime() const
1905{
1906 wxDateTime value;
1907 if (!Convert(& value))
1908 {
1909 wxFAIL_MSG(wxT("Could not convert to a datetime"));
1910 }
1911
1912 return value;
1913}
1914#endif // wxUSE_DATETIME
1915
1916wxList& wxVariant::GetList() const
1917{
1918 wxASSERT( (GetType() == wxT("list")) );
1919
1920 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1921}
1922
1923#if WXWIN_COMPATIBILITY_2_4
1924
1925wxStringList& wxVariant::GetStringList() const
1926{
1927 wxASSERT( (GetType() == wxT("stringlist")) );
1928
1929 return (wxStringList&) ((wxVariantDataStringList*) m_data)->GetValue();
1930}
1931
1932#endif
1933
1934// Make empty list
1935void wxVariant::NullList()
1936{
1937 SetData(new wxVariantDataList());
1938}
1939
1940// Append to list
1941void wxVariant::Append(const wxVariant& value)
1942{
1943 wxList& list = GetList();
1944
1945 list.Append(new wxVariant(value));
1946}
1947
1948// Insert at front of list
1949void wxVariant::Insert(const wxVariant& value)
1950{
1951 wxList& list = GetList();
1952
1953 list.Insert(new wxVariant(value));
1954}
1955
1956// Returns true if the variant is a member of the list
1957bool wxVariant::Member(const wxVariant& value) const
1958{
1959 wxList& list = GetList();
1960
1961 wxList::compatibility_iterator node = list.GetFirst();
1962 while (node)
1963 {
1964 wxVariant* other = (wxVariant*) node->GetData();
1965 if (value == *other)
1966 return true;
1967 node = node->GetNext();
1968 }
1969 return false;
1970}
1971
1972// Deletes the nth element of the list
1973bool wxVariant::Delete(size_t item)
1974{
1975 wxList& list = GetList();
1976
1977 wxASSERT_MSG( (item < list.GetCount()), wxT("Invalid index to Delete") );
1978 wxList::compatibility_iterator node = list.Item(item);
1979 wxVariant* variant = (wxVariant*) node->GetData();
1980 delete variant;
1981 list.Erase(node);
1982 return true;
1983}
1984
1985// Clear list
1986void wxVariant::ClearList()
1987{
1988 if (!IsNull() && (GetType() == wxT("list")))
1989 {
1990 ((wxVariantDataList*) m_data)->Clear();
1991 }
1992 else
1993 {
1994 if (!GetType().IsSameAs(wxT("list")))
1995 {
1996 delete m_data;
1997 m_data = NULL;
1998 }
1999 m_data = new wxVariantDataList;
2000 }
2001}
2002
2003// Type conversion
2004bool wxVariant::Convert(long* value) const
2005{
2006 wxString type(GetType());
2007 if (type == wxT("double"))
2008 *value = (long) (((wxVariantDataReal*)GetData())->GetValue());
2009 else if (type == wxT("long"))
2010 *value = ((wxVariantDataLong*)GetData())->GetValue();
2011#ifdef HAVE_BOOL
2012 else if (type == wxT("bool"))
2013 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
2014#endif
2015 else if (type == wxT("string"))
2016 *value = wxAtol((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
2017 else
2018 return false;
2019
2020 return true;
2021}
2022
2023bool wxVariant::Convert(bool* value) const
2024{
2025 wxString type(GetType());
2026 if (type == wxT("double"))
2027 *value = ((int) (((wxVariantDataReal*)GetData())->GetValue()) != 0);
2028 else if (type == wxT("long"))
2029 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
2030#ifdef HAVE_BOOL
2031 else if (type == wxT("bool"))
2032 *value = ((wxVariantDataBool*)GetData())->GetValue();
2033#endif
2034 else if (type == wxT("string"))
2035 {
2036 wxString val(((wxVariantDataString*)GetData())->GetValue());
2037 val.MakeLower();
2038 if (val == wxT("true") || val == wxT("yes") || val == wxT('1') )
2039 *value = true;
2040 else if (val == wxT("false") || val == wxT("no") || val == wxT('0') )
2041 *value = false;
2042 else
2043 return false;
2044 }
2045 else
2046 return false;
2047
2048 return true;
2049}
2050
2051bool wxVariant::Convert(double* value) const
2052{
2053 wxString type(GetType());
2054 if (type == wxT("double"))
2055 *value = ((wxVariantDataReal*)GetData())->GetValue();
2056 else if (type == wxT("long"))
2057 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
2058#ifdef HAVE_BOOL
2059 else if (type == wxT("bool"))
2060 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
2061#endif
2062 else if (type == wxT("string"))
2063 *value = (double) wxAtof((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
2064 else
2065 return false;
2066
2067 return true;
2068}
2069
2070bool wxVariant::Convert(char* value) const
2071{
2072 wxString type(GetType());
2073 if (type == wxT("char"))
2074 *value = ((wxVariantDataChar*)GetData())->GetValue();
2075 else if (type == wxT("long"))
2076 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
2077#ifdef HAVE_BOOL
2078 else if (type == wxT("bool"))
2079 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
2080#endif
2081 else
2082 return false;
2083
2084 return true;
2085}
2086
2087bool wxVariant::Convert(wxString* value) const
2088{
2089 *value = MakeString();
2090 return true;
2091}
2092
2093#if wxUSE_DATETIME
2094bool wxVariant::Convert(wxDateTime* value) const
2095{
2096 wxString type(GetType());
2097 if (type == wxT("datetime"))
2098 {
2099 *value = ((wxVariantDataDateTime*)GetData())->GetValue();
2100 return true;
2101 }
2102 // Fallback to string conversion
2103 wxString val;
2104 return Convert(&val) &&
2105 (value->ParseDateTime(val) || value->ParseDate(val));
2106}
2107#endif // wxUSE_DATETIME