]> git.saurik.com Git - wxWidgets.git/blob - src/common/variant.cpp
Workaround for memory bug when using wxRegConfig and calling
[wxWidgets.git] / src / common / variant.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "variant.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #if wxUSE_STD_IOSTREAM
24 #if wxUSE_IOSTREAMH
25 #include <fstream.h>
26 #else
27 #include <fstream>
28 #endif
29 #endif
30
31 #if defined(__MWERKS__) && __MSL__ >= 0x6000
32 namespace std {}
33 using namespace std ;
34 #endif
35
36 #if wxUSE_STREAMS
37 #include "wx/stream.h"
38 #include "wx/txtstrm.h"
39 #endif
40
41 #include "wx/string.h"
42 #include "wx/tokenzr.h"
43
44 #include "wx/variant.h"
45
46 IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject)
47
48 wxVariant WXDLLIMPEXP_BASE wxNullVariant;
49
50 /*
51 * wxVariantDataList
52 */
53
54 class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
55 {
56 DECLARE_DYNAMIC_CLASS(wxVariantDataList)
57 public:
58 wxVariantDataList() {}
59 wxVariantDataList(const wxList& list);
60 ~wxVariantDataList();
61
62 wxList& GetValue() const { return (wxList&) m_value; }
63 void SetValue(const wxList& value) ;
64
65 virtual void Copy(wxVariantData& data);
66 virtual bool Eq(wxVariantData& data) const;
67 #if wxUSE_STD_IOSTREAM
68 virtual bool Write(wxSTD ostream& str) const;
69 #endif
70 virtual bool Write(wxString& str) const;
71 #if wxUSE_STD_IOSTREAM
72 virtual bool Read(wxSTD istream& str);
73 #endif
74 virtual bool Read(wxString& str);
75 virtual wxString GetType() const { return wxT("list"); };
76
77 void Clear();
78
79 protected:
80 wxList m_value;
81 };
82
83 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
84
85 wxVariantDataList::wxVariantDataList(const wxList& list)
86 {
87 SetValue(list);
88 }
89
90 wxVariantDataList::~wxVariantDataList()
91 {
92 Clear();
93 }
94
95 void wxVariantDataList::SetValue(const wxList& value)
96 {
97 Clear();
98 wxList::compatibility_iterator node = value.GetFirst();
99 while (node)
100 {
101 wxVariant* var = (wxVariant*) node->GetData();
102 m_value.Append(new wxVariant(*var));
103 node = node->GetNext();
104 }
105 }
106
107 void wxVariantDataList::Clear()
108 {
109 wxList::compatibility_iterator node = m_value.GetFirst();
110 while (node)
111 {
112 wxVariant* var = (wxVariant*) node->GetData();
113 delete var;
114 node = node->GetNext();
115 }
116 m_value.Clear();
117 }
118
119 void wxVariantDataList::Copy(wxVariantData& data)
120 {
121 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Copy: Can't copy to this type of data") );
122
123 wxVariantDataList& listData = (wxVariantDataList&) data;
124
125 listData.Clear();
126 wxList::compatibility_iterator node = m_value.GetFirst();
127 while (node)
128 {
129 wxVariant* var = (wxVariant*) node->GetData();
130 listData.m_value.Append(new wxVariant(*var));
131 node = node->GetNext();
132 }
133 }
134
135 bool wxVariantDataList::Eq(wxVariantData& data) const
136 {
137 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
138
139 wxVariantDataList& listData = (wxVariantDataList&) data;
140 wxList::compatibility_iterator node1 = m_value.GetFirst();
141 wxList::compatibility_iterator node2 = listData.GetValue().GetFirst();
142 while (node1 && node2)
143 {
144 wxVariant* var1 = (wxVariant*) node1->GetData();
145 wxVariant* var2 = (wxVariant*) node2->GetData();
146 if ((*var1) != (*var2))
147 return false;
148 node1 = node1->GetNext();
149 node2 = node2->GetNext();
150 }
151 if (node1 || node2) return false;
152 return true;
153 }
154
155 #if wxUSE_STD_IOSTREAM
156 bool wxVariantDataList::Write(wxSTD ostream& str) const
157 {
158 wxString s;
159 Write(s);
160 str << (const char*) s.mb_str();
161 return true;
162 }
163 #endif
164
165 bool wxVariantDataList::Write(wxString& str) const
166 {
167 str = wxT("");
168 wxList::compatibility_iterator node = m_value.GetFirst();
169 while (node)
170 {
171 wxVariant* var = (wxVariant*) node->GetData();
172 if (node != m_value.GetFirst())
173 str += wxT(" ");
174 wxString str1;
175 str += var->MakeString();
176 node = node->GetNext();
177 }
178
179 return true;
180 }
181
182 #if wxUSE_STD_IOSTREAM
183 bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
184 {
185 wxFAIL_MSG(wxT("Unimplemented"));
186 // TODO
187 return false;
188 }
189 #endif
190
191 bool wxVariantDataList::Read(wxString& WXUNUSED(str))
192 {
193 wxFAIL_MSG(wxT("Unimplemented"));
194 // TODO
195 return false;
196 }
197
198 /*
199 * wxVariantDataStringList
200 */
201
202 class WXDLLIMPEXP_BASE wxVariantDataStringList: public wxVariantData
203 {
204 DECLARE_DYNAMIC_CLASS(wxVariantDataStringList)
205 public:
206 wxVariantDataStringList() {}
207 wxVariantDataStringList(const wxStringList& list) { m_value = list; }
208
209 wxStringList& GetValue() const { return (wxStringList&) m_value; }
210 void SetValue(const wxStringList& value);
211
212 virtual void Copy(wxVariantData& data);
213 virtual bool Eq(wxVariantData& data) const;
214 #if wxUSE_STD_IOSTREAM
215 virtual bool Write(wxSTD ostream& str) const;
216 #endif
217 virtual bool Write(wxString& str) const;
218 #if wxUSE_STD_IOSTREAM
219 virtual bool Read(wxSTD istream& str);
220 #endif
221 virtual bool Read(wxString& str);
222 virtual wxString GetType() const { return wxT("stringlist"); };
223
224 protected:
225 wxStringList m_value;
226 };
227
228 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataStringList, wxVariantData)
229
230 void wxVariantDataStringList::SetValue(const wxStringList& value)
231 {
232 m_value = value;
233 }
234
235 void wxVariantDataStringList::Copy(wxVariantData& data)
236 {
237 wxASSERT_MSG( (data.GetType() == wxT("stringlist")), wxT("wxVariantDataStringList::Copy: Can't copy to this type of data") );
238
239 wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
240
241 listData.m_value = m_value ;
242 }
243
244 bool wxVariantDataStringList::Eq(wxVariantData& data) const
245 {
246 wxASSERT_MSG( (data.GetType() == wxT("stringlist")), wxT("wxVariantDataStringList::Eq: argument mismatch") );
247
248 wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
249 wxStringList::compatibility_iterator node1 = m_value.GetFirst();
250 wxStringList::compatibility_iterator node2 = listData.GetValue().GetFirst();
251 while (node1 && node2)
252 {
253 wxString str1 ( node1->GetData() );
254 wxString str2 ( node2->GetData() );
255 if (str1 != str2)
256 return false;
257 node1 = node1->GetNext();
258 node2 = node2->GetNext();
259 }
260 if (node1 || node2) return false;
261 return true;
262 }
263
264 #if wxUSE_STD_IOSTREAM
265 bool wxVariantDataStringList::Write(wxSTD ostream& str) const
266 {
267 wxString s;
268 Write(s);
269 str << (const char*) s.mb_str();
270 return true;
271 }
272 #endif
273
274 bool wxVariantDataStringList::Write(wxString& str) const
275 {
276 str.Empty();
277 wxStringList::compatibility_iterator node = m_value.GetFirst();
278 while (node)
279 {
280 const wxChar* s = node->GetData();
281 if (node != m_value.GetFirst())
282 str += wxT(" ");
283 str += s;
284 node = node->GetNext();
285 }
286
287 return true;
288 }
289
290 #if wxUSE_STD_IOSTREAM
291 bool wxVariantDataStringList::Read(wxSTD istream& WXUNUSED(str))
292 {
293 wxFAIL_MSG(wxT("Unimplemented"));
294 // TODO
295 return false;
296 }
297 #endif
298
299 bool wxVariantDataStringList::Read(wxString& WXUNUSED(str))
300 {
301 wxFAIL_MSG(wxT("Unimplemented"));
302 // TODO
303 return false;
304 }
305
306 /*
307 * wxVariantDataLong
308 */
309
310 class WXDLLIMPEXP_BASE wxVariantDataLong: public wxVariantData
311 {
312 DECLARE_DYNAMIC_CLASS(wxVariantDataLong)
313 public:
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
336 protected:
337 long m_value;
338 };
339
340 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataLong, wxVariantData)
341
342 void 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
351 bool 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
361 bool 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
370 bool wxVariantDataLong::Write(wxString& str) const
371 {
372 str.Printf(wxT("%ld"), m_value);
373 return true;
374 }
375
376 #if wxUSE_STD_IOSTREAM
377 bool wxVariantDataLong::Read(wxSTD istream& str)
378 {
379 str >> m_value;
380 return true;
381 }
382 #endif
383
384 #if wxUSE_STREAMS
385 bool wxVariantDataLong::Write(wxOutputStream& str) const
386 {
387 wxTextOutputStream s(str);
388
389 s.Write32((size_t)m_value);
390 return true;
391 }
392
393 bool wxVariantDataLong::Read(wxInputStream& str)
394 {
395 wxTextInputStream s(str);
396 m_value = s.Read32();
397 return true;
398 }
399 #endif // wxUSE_STREAMS
400
401 bool wxVariantDataLong::Read(wxString& str)
402 {
403 m_value = wxAtol((const wxChar*) str);
404 return true;
405 }
406
407 /*
408 * wxVariantDataReal
409 */
410
411 class WXDLLIMPEXP_BASE wxVariantDataReal: public wxVariantData
412 {
413 DECLARE_DYNAMIC_CLASS(wxVariantDataReal)
414 public:
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
437 protected:
438 double m_value;
439 };
440
441 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataReal, wxVariantData)
442
443 void 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
452 bool 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 (otherData.m_value == m_value);
459 }
460
461 #if wxUSE_STD_IOSTREAM
462 bool 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
471 bool wxVariantDataReal::Write(wxString& str) const
472 {
473 str.Printf(wxT("%.4f"), m_value);
474 return true;
475 }
476
477 #if wxUSE_STD_IOSTREAM
478 bool wxVariantDataReal::Read(wxSTD istream& str)
479 {
480 str >> m_value;
481 return true;
482 }
483 #endif
484
485 #if wxUSE_STREAMS
486 bool wxVariantDataReal::Write(wxOutputStream& str) const
487 {
488 wxTextOutputStream s(str);
489 s.WriteDouble((double)m_value);
490 return true;
491 }
492
493 bool wxVariantDataReal::Read(wxInputStream& str)
494 {
495 wxTextInputStream s(str);
496 m_value = (float)s.ReadDouble();
497 return true;
498 }
499 #endif // wxUSE_STREAMS
500
501 bool 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
512 class WXDLLIMPEXP_BASE wxVariantDataBool: public wxVariantData
513 {
514 DECLARE_DYNAMIC_CLASS(wxVariantDataBool)
515 public:
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
538 protected:
539 bool m_value;
540 };
541
542 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataBool, wxVariantData)
543
544 void 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
553 bool 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
563 bool 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
572 bool wxVariantDataBool::Write(wxString& str) const
573 {
574 str.Printf(wxT("%d"), (int) m_value);
575 return true;
576 }
577
578 #if wxUSE_STD_IOSTREAM
579 bool 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
588 bool wxVariantDataBool::Write(wxOutputStream& str) const
589 {
590 wxTextOutputStream s(str);
591
592 s.Write8(m_value);
593 return true;
594 }
595
596 bool 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
605 bool 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
616 class WXDLLIMPEXP_BASE wxVariantDataChar: public wxVariantData
617 {
618 DECLARE_DYNAMIC_CLASS(wxVariantDataChar)
619 public:
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
640 protected:
641 char m_value;
642 };
643
644 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataChar, wxVariantData)
645
646 void 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
655 bool 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
665 bool 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
674 bool wxVariantDataChar::Write(wxString& str) const
675 {
676 str.Printf(wxT("%c"), m_value);
677 return true;
678 }
679
680 #if wxUSE_STD_IOSTREAM
681 bool 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
690 bool wxVariantDataChar::Write(wxOutputStream& str) const
691 {
692 wxTextOutputStream s(str);
693
694 s.Write8(m_value);
695 return true;
696 }
697
698 bool wxVariantDataChar::Read(wxInputStream& str)
699 {
700 wxTextInputStream s(str);
701
702 m_value = s.Read8();
703 return true;
704 }
705 #endif // wxUSE_STREAMS
706
707 bool wxVariantDataChar::Read(wxString& str)
708 {
709 m_value = str.ToAscii()[0u];
710 return true;
711 }
712
713 /*
714 * wxVariantDataString
715 */
716
717 class WXDLLIMPEXP_BASE wxVariantDataString: public wxVariantData
718 {
719 DECLARE_DYNAMIC_CLASS(wxVariantDataString)
720 public:
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
743 protected:
744 wxString m_value;
745 };
746
747 void 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
756 bool 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
766 bool wxVariantDataString::Write(wxSTD ostream& str) const
767 {
768 str << (const char*) m_value.mb_str();
769 return true;
770 }
771 #endif
772
773 bool wxVariantDataString::Write(wxString& str) const
774 {
775 str = m_value;
776 return true;
777 }
778
779 #if wxUSE_STD_IOSTREAM
780 bool wxVariantDataString::Read(wxSTD istream& str)
781 {
782 str >> m_value;
783 return true;
784 }
785 #endif
786
787 #if wxUSE_STREAMS
788 bool 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
796 bool wxVariantDataString::Read(wxInputStream& str)
797 {
798 wxTextInputStream s(str);
799
800 m_value = s.ReadString();
801 return true;
802 }
803 #endif // wxUSE_STREAMS
804
805 bool wxVariantDataString::Read(wxString& str)
806 {
807 m_value = str;
808 return true;
809 }
810
811 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
812
813 /*
814 * wxVariantDataVoidPtr
815 */
816
817 class wxVariantDataVoidPtr: public wxVariantData
818 {
819 DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
820 public:
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
840 protected:
841 void* m_value;
842
843 DECLARE_NO_COPY_CLASS(wxVariantDataVoidPtr)
844 };
845
846 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
847
848 void 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
857 bool 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
867 bool 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
876 bool wxVariantDataVoidPtr::Write(wxString& str) const
877 {
878 str.Printf(wxT("%ld"), (long) m_value);
879 return true;
880 }
881
882 #if wxUSE_STD_IOSTREAM
883 bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
884 {
885 // Not implemented
886 return false;
887 }
888 #endif
889
890 bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
891 {
892 // Not implemented
893 return false;
894 }
895
896 /*
897 * wxVariantDataWxObjectPtr
898 */
899
900 class wxVariantDataWxObjectPtr: public wxVariantData
901 {
902 DECLARE_DYNAMIC_CLASS(wxVariantDataWxObjectPtr)
903 public:
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() ;
924 protected:
925 wxObject* m_value;
926
927 DECLARE_NO_COPY_CLASS(wxVariantDataWxObjectPtr)
928 };
929
930 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataWxObjectPtr, wxVariantData)
931
932 void 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
943 bool 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
952 wxString 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
961 wxClassInfo* 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
971 bool 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
980 bool wxVariantDataWxObjectPtr::Write(wxString& str) const
981 {
982 str.Printf(wxT("%s(%ld)"), GetType().c_str(), (long) m_value);
983 return true;
984 }
985
986 #if wxUSE_STD_IOSTREAM
987 bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
988 {
989 // Not implemented
990 return false;
991 }
992 #endif
993
994 bool 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
1007 class wxVariantDataDateTime: public wxVariantData
1008 {
1009 DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime)
1010
1011 public:
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
1040 protected:
1041 wxDateTime m_value;
1042 };
1043
1044
1045 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime, wxVariantData)
1046
1047 void 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
1057 bool 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
1068 bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
1069 {
1070 // Not implemented
1071 return false;
1072 }
1073 #endif
1074
1075
1076 bool wxVariantDataDateTime::Write(wxString& str) const
1077 {
1078 str = m_value.Format();
1079 return true;
1080 }
1081
1082
1083 #if wxUSE_STD_IOSTREAM
1084 bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
1085 {
1086 // Not implemented
1087 return false;
1088 }
1089 #endif
1090
1091
1092 bool 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
1105 class wxVariantDataArrayString: public wxVariantData
1106 {
1107 public:
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
1127 protected:
1128 wxArrayString m_value;
1129
1130 DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString)
1131 };
1132
1133 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString, wxVariantData)
1134
1135 void 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
1145 bool 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
1156 bool wxVariantDataArrayString::Write(wxSTD ostream& str) const
1157 {
1158 // Not implemented
1159 return false;
1160 }
1161 #endif
1162
1163
1164 bool 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
1180 bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
1181 {
1182 // Not implemented
1183 return false;
1184 }
1185 #endif
1186
1187
1188 bool 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
1205 IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
1206
1207 // Construction & destruction
1208 wxVariant::wxVariant()
1209 {
1210 m_data = (wxVariantData*) NULL;
1211 }
1212
1213 wxVariant::wxVariant(double val, const wxString& name)
1214 {
1215 m_data = new wxVariantDataReal(val);
1216 m_name = name;
1217 }
1218
1219 wxVariant::wxVariant(long val, const wxString& name)
1220 {
1221 m_data = new wxVariantDataLong(val);
1222 m_name = name;
1223 }
1224
1225 #ifdef HAVE_BOOL
1226 wxVariant::wxVariant(bool val, const wxString& name)
1227 {
1228 m_data = new wxVariantDataBool(val);
1229 m_name = name;
1230 }
1231 #endif
1232
1233 wxVariant::wxVariant(char val, const wxString& name)
1234 {
1235 m_data = new wxVariantDataChar(val);
1236 m_name = name;
1237 }
1238
1239 wxVariant::wxVariant(const wxString& val, const wxString& name)
1240 {
1241 m_data = new wxVariantDataString(val);
1242 m_name = name;
1243 }
1244
1245 wxVariant::wxVariant(const wxChar* val, const wxString& name)
1246 {
1247 m_data = new wxVariantDataString(wxString(val));
1248 m_name = name;
1249 }
1250
1251 wxVariant::wxVariant(const wxStringList& val, const wxString& name)
1252 {
1253 m_data = new wxVariantDataStringList(val);
1254 m_name = name;
1255 }
1256
1257 wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
1258 {
1259 m_data = new wxVariantDataList(val);
1260 m_name = name;
1261 }
1262
1263 wxVariant::wxVariant( void* val, const wxString& name)
1264 {
1265 m_data = new wxVariantDataVoidPtr(val);
1266 m_name = name;
1267 }
1268
1269 wxVariant::wxVariant( wxObject* val, const wxString& name)
1270 {
1271 m_data = new wxVariantDataWxObjectPtr(val);
1272 m_name = name;
1273 }
1274
1275 #if wxUSE_DATETIME
1276 wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1277 {
1278 m_data = new wxVariantDataDateTime(val);
1279 m_name = name;
1280 }
1281 #endif // wxUSE_DATETIME
1282
1283 #if wxUSE_ODBC
1284 wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1285 {
1286 m_data = new wxVariantDataDateTime(valptr);
1287 m_name = name;
1288 }
1289
1290 wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1291 {
1292 m_data = new wxVariantDataDateTime(valptr);
1293 m_name = name;
1294 }
1295
1296 wxVariant::wxVariant(const DATE_STRUCT* valptr, const wxString& name) // Date
1297 {
1298 m_data = new wxVariantDataDateTime(valptr);
1299 m_name = name;
1300 }
1301 #endif // wxUSE_ODBC
1302
1303 wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1304 {
1305 m_data = new wxVariantDataArrayString(val);
1306 m_name = name;
1307 }
1308
1309 wxVariant::wxVariant(const wxVariant& variant)
1310 : wxObject()
1311 {
1312 if (!variant.IsNull())
1313 {
1314 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1315 variant.m_data->Copy(*m_data);
1316 }
1317 else
1318 m_data = (wxVariantData*) NULL;
1319 m_name = variant.m_name;
1320 }
1321
1322 wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
1323 {
1324 m_data = data;
1325 m_name = name;
1326 }
1327
1328 wxVariant::~wxVariant()
1329 {
1330 delete m_data;
1331 }
1332
1333
1334 // Make NULL (i.e. delete the data)
1335 void wxVariant::MakeNull()
1336 {
1337 delete m_data;
1338 m_data = NULL;
1339 }
1340
1341 // Generic operators
1342 // Assignment
1343 void wxVariant::operator= (const wxVariant& variant)
1344 {
1345 if (variant.IsNull())
1346 {
1347 MakeNull();
1348 return;
1349 }
1350
1351 if (IsNull() || (GetType() != variant.GetType()))
1352 {
1353 if (m_data)
1354 delete m_data;
1355 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1356 }
1357
1358 variant.GetData()->Copy(* GetData());
1359
1360 m_name = variant.m_name;
1361 }
1362
1363 // Assignment using data, e.g.
1364 // myVariant = new wxStringVariantData("hello")
1365 void wxVariant::operator= (wxVariantData* variantData)
1366 {
1367 MakeNull();
1368 m_data = variantData;
1369 }
1370
1371 bool wxVariant::operator== (const wxVariant& variant) const
1372 {
1373 if (IsNull() || variant.IsNull())
1374 return (IsNull() == variant.IsNull());
1375
1376 return (GetData()->Eq(* variant.GetData()));
1377 }
1378
1379 bool wxVariant::operator!= (const wxVariant& variant) const
1380 {
1381 return (!(*this == variant));
1382 }
1383
1384
1385 // Specific operators
1386 bool wxVariant::operator== (double value) const
1387 {
1388 double thisValue;
1389 if (!Convert(&thisValue))
1390 return false;
1391 else
1392 return (value == thisValue);
1393 }
1394
1395 bool wxVariant::operator!= (double value) const
1396 {
1397 return (!((*this) == value));
1398 }
1399
1400 void wxVariant::operator= (double value)
1401 {
1402 if (GetType() == wxT("double"))
1403 {
1404 ((wxVariantDataReal*)GetData())->SetValue(value);
1405 }
1406 else
1407 {
1408 if (m_data)
1409 delete m_data;
1410 m_data = new wxVariantDataReal(value);
1411 }
1412 }
1413
1414 bool wxVariant::operator== (long value) const
1415 {
1416 long thisValue;
1417 if (!Convert(&thisValue))
1418 return false;
1419 else
1420 return (value == thisValue);
1421 }
1422
1423 bool wxVariant::operator!= (long value) const
1424 {
1425 return (!((*this) == value));
1426 }
1427
1428 void wxVariant::operator= (long value)
1429 {
1430 if (GetType() == wxT("long"))
1431 {
1432 ((wxVariantDataLong*)GetData())->SetValue(value);
1433 }
1434 else
1435 {
1436 if (m_data)
1437 delete m_data;
1438 m_data = new wxVariantDataLong(value);
1439 }
1440 }
1441
1442 bool wxVariant::operator== (char value) const
1443 {
1444 char thisValue;
1445 if (!Convert(&thisValue))
1446 return false;
1447 else
1448 return (value == thisValue);
1449 }
1450
1451 bool wxVariant::operator!= (char value) const
1452 {
1453 return (!((*this) == value));
1454 }
1455
1456 void wxVariant::operator= (char value)
1457 {
1458 if (GetType() == wxT("char"))
1459 {
1460 ((wxVariantDataChar*)GetData())->SetValue(value);
1461 }
1462 else
1463 {
1464 if (m_data)
1465 delete m_data;
1466 m_data = new wxVariantDataChar(value);
1467 }
1468 }
1469
1470 #ifdef HAVE_BOOL
1471 bool wxVariant::operator== (bool value) const
1472 {
1473 bool thisValue;
1474 if (!Convert(&thisValue))
1475 return false;
1476 else
1477 return (value == thisValue);
1478 }
1479
1480 bool wxVariant::operator!= (bool value) const
1481 {
1482 return (!((*this) == value));
1483 }
1484
1485 void wxVariant::operator= (bool value)
1486 {
1487 if (GetType() == wxT("bool"))
1488 {
1489 ((wxVariantDataBool*)GetData())->SetValue(value);
1490 }
1491 else
1492 {
1493 if (m_data)
1494 delete m_data;
1495 m_data = new wxVariantDataBool(value);
1496 }
1497 }
1498 #endif // HAVE_BOOL
1499
1500 bool wxVariant::operator== (const wxString& value) const
1501 {
1502 wxString thisValue;
1503 if (!Convert(&thisValue))
1504 return false;
1505
1506 return value == thisValue;
1507 }
1508
1509 bool wxVariant::operator!= (const wxString& value) const
1510 {
1511 return (!((*this) == value));
1512 }
1513
1514 void wxVariant::operator= (const wxString& value)
1515 {
1516 if (GetType() == wxT("string"))
1517 {
1518 ((wxVariantDataString*)GetData())->SetValue(value);
1519 }
1520 else
1521 {
1522 if (m_data)
1523 delete m_data;
1524 m_data = new wxVariantDataString(value);
1525 }
1526 }
1527
1528 void wxVariant::operator= (const wxChar* value)
1529 {
1530 if (GetType() == wxT("string"))
1531 {
1532 ((wxVariantDataString*)GetData())->SetValue(wxString(value));
1533 }
1534 else
1535 {
1536 if (m_data)
1537 delete m_data;
1538 m_data = new wxVariantDataString(wxString(value));
1539 }
1540 }
1541
1542 bool wxVariant::operator== (const wxStringList& value) const
1543 {
1544 wxASSERT_MSG( (GetType() == wxT("stringlist")), wxT("Invalid type for == operator") );
1545
1546 wxVariantDataStringList other(value);
1547 return (m_data->Eq(other));
1548 }
1549
1550 bool wxVariant::operator!= (const wxStringList& value) const
1551 {
1552 return (!((*this) == value));
1553 }
1554
1555 void wxVariant::operator= (const wxStringList& value)
1556 {
1557 if (GetType() == wxT("stringlist"))
1558 {
1559 ((wxVariantDataStringList*)GetData())->SetValue(value);
1560 }
1561 else
1562 {
1563 if (m_data)
1564 delete m_data;
1565 m_data = new wxVariantDataStringList(value);
1566 }
1567 }
1568
1569 bool wxVariant::operator== (const wxList& value) const
1570 {
1571 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1572
1573 wxVariantDataList other(value);
1574 return (m_data->Eq(other));
1575 }
1576
1577 bool wxVariant::operator!= (const wxList& value) const
1578 {
1579 return (!((*this) == value));
1580 }
1581
1582 void wxVariant::operator= (const wxList& value)
1583 {
1584 if (GetType() == wxT("list"))
1585 {
1586 ((wxVariantDataList*)GetData())->SetValue(value);
1587 }
1588 else
1589 {
1590 if (m_data)
1591 delete m_data;
1592 m_data = new wxVariantDataList(value);
1593 }
1594 }
1595
1596 bool wxVariant::operator== (void* value) const
1597 {
1598 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
1599 }
1600
1601 bool wxVariant::operator!= (void* value) const
1602 {
1603 return (!((*this) == (void*) value));
1604 }
1605
1606 void wxVariant::operator= (void* value)
1607 {
1608 if (GetType() == wxT("void*"))
1609 {
1610 ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1611 }
1612 else
1613 {
1614 if (m_data)
1615 delete m_data;
1616 m_data = new wxVariantDataVoidPtr(value);
1617 }
1618 }
1619
1620 #if wxUSE_DATETIME
1621 bool wxVariant::operator== (const wxDateTime& value) const
1622 {
1623 wxDateTime thisValue;
1624 if (!Convert(&thisValue))
1625 return false;
1626
1627 return value.IsEqualTo(thisValue);
1628 }
1629
1630 bool wxVariant::operator!= (const wxDateTime& value) const
1631 {
1632 return (!((*this) == value));
1633 }
1634
1635 void wxVariant::operator= (const wxDateTime& value)
1636 {
1637 if (GetType() == wxT("datetime"))
1638 {
1639 ((wxVariantDataDateTime*)GetData())->SetValue(value);
1640 }
1641 else
1642 {
1643 if (m_data)
1644 delete m_data;
1645 m_data = new wxVariantDataDateTime(value);
1646 }
1647 }
1648 #endif // wxUSE_DATETIME
1649
1650 #if wxUSE_ODBC
1651 void wxVariant::operator= (const DATE_STRUCT* value)
1652 {
1653 if (m_data)
1654 delete m_data;
1655 m_data = new wxVariantDataDateTime(value);
1656 }
1657
1658
1659 void wxVariant::operator= (const TIME_STRUCT* value)
1660 {
1661 if (m_data)
1662 delete m_data;
1663 m_data = new wxVariantDataDateTime(value);
1664 }
1665
1666
1667 void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
1668 {
1669 if (m_data)
1670 delete m_data;
1671 m_data = new wxVariantDataDateTime(value);
1672 }
1673
1674 #endif // wxUSE_ODBC
1675
1676 bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
1677 {
1678 wxFAIL_MSG( _T("TODO") );
1679
1680 return false;
1681 }
1682
1683 bool wxVariant::operator!=(const wxArrayString& value) const
1684 {
1685 return !(*this == value);
1686 }
1687
1688 void wxVariant::operator=(const wxArrayString& value)
1689 {
1690 if (GetType() == wxT("arrstring"))
1691 {
1692 ((wxVariantDataArrayString *)GetData())->SetValue(value);
1693 }
1694 else
1695 {
1696 delete m_data;
1697 m_data = new wxVariantDataArrayString(value);
1698 }
1699 }
1700
1701 wxArrayString wxVariant::GetArrayString() const
1702 {
1703 if ( GetType() == wxT("arrstring") )
1704 return ((wxVariantDataArrayString *)GetData())->GetValue();
1705
1706 return wxArrayString();
1707 }
1708
1709
1710 // Treat a list variant as an array
1711 wxVariant wxVariant::operator[] (size_t idx) const
1712 {
1713 wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for array operator") );
1714
1715 if (GetType() == wxT("list"))
1716 {
1717 wxVariantDataList* data = (wxVariantDataList*) m_data;
1718 wxASSERT_MSG( (idx < (size_t) data->GetValue().GetCount()), wxT("Invalid index for array") );
1719 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1720 }
1721 else if (GetType() == wxT("stringlist"))
1722 {
1723 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1724 wxASSERT_MSG( (idx < (size_t) data->GetValue().GetCount()), wxT("Invalid index for array") );
1725
1726 wxString str( (const wxChar*) (data->GetValue().Item(idx)->GetData()) );
1727 wxVariant variant( str );
1728 return variant;
1729 }
1730 return wxNullVariant;
1731 }
1732
1733 wxVariant& wxVariant::operator[] (size_t idx)
1734 {
1735 // We can't return a reference to a variant for a string list, since the string
1736 // is actually stored as a char*, not a variant.
1737
1738 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1739
1740 wxVariantDataList* data = (wxVariantDataList*) m_data;
1741 wxASSERT_MSG( (idx < (size_t) data->GetValue().GetCount()), wxT("Invalid index for array") );
1742
1743 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1744 }
1745
1746 // Return the number of elements in a list
1747 int wxVariant::GetCount() const
1748 {
1749 wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for GetCount()") );
1750
1751 if (GetType() == wxT("list"))
1752 {
1753 wxVariantDataList* data = (wxVariantDataList*) m_data;
1754 return data->GetValue().GetCount();
1755 }
1756 else if (GetType() == wxT("stringlist"))
1757 {
1758 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1759 return data->GetValue().GetCount();
1760 }
1761 return 0;
1762 }
1763
1764 wxString wxVariant::MakeString() const
1765 {
1766 if (!IsNull())
1767 {
1768 wxString str;
1769 if (GetData()->Write(str))
1770 return str;
1771 }
1772 return wxString(wxT(""));
1773 }
1774
1775 // Accessors
1776
1777 void wxVariant::SetData(wxVariantData* data)
1778 {
1779 if (m_data) delete m_data;
1780 m_data = data;
1781 }
1782
1783
1784 // Returns a string representing the type of the variant,
1785 // e.g. "string", "bool", "stringlist", "list", "double", "long"
1786 wxString wxVariant::GetType() const
1787 {
1788 if (IsNull())
1789 return wxString(wxT("null"));
1790 else
1791 return m_data->GetType();
1792 }
1793
1794
1795 bool wxVariant::IsType(const wxString& type) const
1796 {
1797 return (GetType() == type);
1798 }
1799
1800 bool wxVariant::IsValueKindOf(const wxClassInfo* type) const
1801 {
1802 wxClassInfo* info=m_data->GetValueClassInfo();
1803 return info ? info->IsKindOf(type) : false ;
1804 }
1805
1806
1807 // Value accessors
1808 double wxVariant::GetReal() const
1809 {
1810 double value;
1811 if (Convert(& value))
1812 return value;
1813 else
1814 {
1815 wxFAIL_MSG(wxT("Could not convert to a real number"));
1816 return 0.0;
1817 }
1818 }
1819
1820 long wxVariant::GetInteger() const
1821 {
1822 long value;
1823 if (Convert(& value))
1824 return value;
1825 else
1826 {
1827 wxFAIL_MSG(wxT("Could not convert to an integer"));
1828 return 0;
1829 }
1830 }
1831
1832 char wxVariant::GetChar() const
1833 {
1834 char value;
1835 if (Convert(& value))
1836 return value;
1837 else
1838 {
1839 wxFAIL_MSG(wxT("Could not convert to a char"));
1840 return 0;
1841 }
1842 }
1843
1844 bool wxVariant::GetBool() const
1845 {
1846 bool value;
1847 if (Convert(& value))
1848 return value;
1849 else
1850 {
1851 wxFAIL_MSG(wxT("Could not convert to a bool"));
1852 return 0;
1853 }
1854 }
1855
1856 wxString wxVariant::GetString() const
1857 {
1858 wxString value;
1859 if (!Convert(& value))
1860 {
1861 wxFAIL_MSG(wxT("Could not convert to a string"));
1862 }
1863
1864 return value;
1865 }
1866
1867 void* wxVariant::GetVoidPtr() const
1868 {
1869 wxASSERT( (GetType() == wxT("void*")) );
1870
1871 return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
1872 }
1873
1874 wxObject* wxVariant::GetWxObjectPtr()
1875 {
1876 wxASSERT(wxIsKindOf(m_data, wxVariantDataWxObjectPtr));
1877 return (wxObject*) ((wxVariantDataWxObjectPtr*) m_data)->GetValue();
1878 }
1879
1880 #if wxUSE_DATETIME
1881 wxDateTime wxVariant::GetDateTime() const
1882 {
1883 wxDateTime value;
1884 if (!Convert(& value))
1885 {
1886 wxFAIL_MSG(wxT("Could not convert to a datetime"));
1887 }
1888
1889 return value;
1890 }
1891 #endif // wxUSE_DATETIME
1892
1893 wxList& wxVariant::GetList() const
1894 {
1895 wxASSERT( (GetType() == wxT("list")) );
1896
1897 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1898 }
1899
1900 wxStringList& wxVariant::GetStringList() const
1901 {
1902 wxASSERT( (GetType() == wxT("stringlist")) );
1903
1904 return (wxStringList&) ((wxVariantDataStringList*) m_data)->GetValue();
1905 }
1906
1907 // Make empty list
1908 void wxVariant::NullList()
1909 {
1910 SetData(new wxVariantDataList());
1911 };
1912
1913 // Append to list
1914 void wxVariant::Append(const wxVariant& value)
1915 {
1916 wxList& list = GetList();
1917
1918 list.Append(new wxVariant(value));
1919 }
1920
1921 // Insert at front of list
1922 void wxVariant::Insert(const wxVariant& value)
1923 {
1924 wxList& list = GetList();
1925
1926 list.Insert(new wxVariant(value));
1927 }
1928
1929 // Returns true if the variant is a member of the list
1930 bool wxVariant::Member(const wxVariant& value) const
1931 {
1932 wxList& list = GetList();
1933
1934 wxList::compatibility_iterator node = list.GetFirst();
1935 while (node)
1936 {
1937 wxVariant* other = (wxVariant*) node->GetData();
1938 if (value == *other)
1939 return true;
1940 node = node->GetNext();
1941 }
1942 return false;
1943 }
1944
1945 // Deletes the nth element of the list
1946 bool wxVariant::Delete(int item)
1947 {
1948 wxList& list = GetList();
1949
1950 wxASSERT_MSG( (item < (int) list.GetCount()), wxT("Invalid index to Delete") );
1951 wxList::compatibility_iterator node = list.Item(item);
1952 wxVariant* variant = (wxVariant*) node->GetData();
1953 delete variant;
1954 list.Erase(node);
1955 return true;
1956 }
1957
1958 // Clear list
1959 void wxVariant::ClearList()
1960 {
1961 if (!IsNull() && (GetType() == wxT("list")))
1962 {
1963 ((wxVariantDataList*) m_data)->Clear();
1964 }
1965 else
1966 {
1967 if (GetType() != wxT("list"))
1968 {
1969 delete m_data;
1970 m_data = NULL;
1971 }
1972 m_data = new wxVariantDataList;
1973 }
1974 }
1975
1976 // Type conversion
1977 bool wxVariant::Convert(long* value) const
1978 {
1979 wxString type(GetType());
1980 if (type == wxT("double"))
1981 *value = (long) (((wxVariantDataReal*)GetData())->GetValue());
1982 else if (type == wxT("long"))
1983 *value = ((wxVariantDataLong*)GetData())->GetValue();
1984 #ifdef HAVE_BOOL
1985 else if (type == wxT("bool"))
1986 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
1987 #endif
1988 else if (type == wxT("string"))
1989 *value = wxAtol((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
1990 else
1991 return false;
1992
1993 return true;
1994 }
1995
1996 bool wxVariant::Convert(bool* value) const
1997 {
1998 wxString type(GetType());
1999 if (type == wxT("double"))
2000 *value = ((int) (((wxVariantDataReal*)GetData())->GetValue()) != 0);
2001 else if (type == wxT("long"))
2002 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
2003 #ifdef HAVE_BOOL
2004 else if (type == wxT("bool"))
2005 *value = ((wxVariantDataBool*)GetData())->GetValue();
2006 #endif
2007 else if (type == wxT("string"))
2008 {
2009 wxString val(((wxVariantDataString*)GetData())->GetValue());
2010 val.MakeLower();
2011 if (val == wxT("true") || val == wxT("yes"))
2012 *value = true;
2013 else if (val == wxT("false") || val == wxT("no"))
2014 *value = false;
2015 else
2016 return false;
2017 }
2018 else
2019 return false;
2020
2021 return true;
2022 }
2023
2024 bool wxVariant::Convert(double* value) const
2025 {
2026 wxString type(GetType());
2027 if (type == wxT("double"))
2028 *value = ((wxVariantDataReal*)GetData())->GetValue();
2029 else if (type == wxT("long"))
2030 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
2031 #ifdef HAVE_BOOL
2032 else if (type == wxT("bool"))
2033 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
2034 #endif
2035 else if (type == wxT("string"))
2036 *value = (double) wxAtof((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
2037 else
2038 return false;
2039
2040 return true;
2041 }
2042
2043 bool wxVariant::Convert(char* value) const
2044 {
2045 wxString type(GetType());
2046 if (type == wxT("char"))
2047 *value = ((wxVariantDataChar*)GetData())->GetValue();
2048 else if (type == wxT("long"))
2049 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
2050 #ifdef HAVE_BOOL
2051 else if (type == wxT("bool"))
2052 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
2053 #endif
2054 else
2055 return false;
2056
2057 return true;
2058 }
2059
2060 bool wxVariant::Convert(wxString* value) const
2061 {
2062 *value = MakeString();
2063 return true;
2064 }
2065
2066 #if wxUSE_DATETIME
2067 bool wxVariant::Convert(wxDateTime* value) const
2068 {
2069 wxString type(GetType());
2070 if (type == wxT("datetime"))
2071 {
2072 *value = ((wxVariantDataDateTime*)GetData())->GetValue();
2073 return true;
2074 }
2075 // Fallback to string conversion
2076 wxString val;
2077 return Convert(&val) && (value->ParseDate(val));
2078 }
2079 #endif // wxUSE_DATETIME
2080