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