]> git.saurik.com Git - wxWidgets.git/blame - src/common/variant.cpp
making things compile and build again ...
[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; }
1202#if wxUSE_ODBC
1203 wxVariantDataDateTime(const TIME_STRUCT* valptr)
1204 { m_value = wxDateTime(valptr->hour, valptr->minute, valptr->second); }
1205 wxVariantDataDateTime(const DATE_STRUCT* valptr)
1206 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1),valptr->year); }
1207 wxVariantDataDateTime(const TIMESTAMP_STRUCT* valptr)
1208 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1), valptr->year,
1209 valptr->hour, valptr->minute, valptr->second, (wxDateTime::wxDateTime_t)valptr->fraction ); }
1210#endif //ODBC
fb42d7c3 1211
2562c823
RR
1212 inline wxDateTime GetValue() const { return m_value; }
1213 inline void SetValue(const wxDateTime& value) { m_value = value; }
fb42d7c3 1214
fb42d7c3
VZ
1215 virtual bool Eq(wxVariantData& data) const;
1216#if wxUSE_STD_IOSTREAM
1217 virtual bool Write(wxSTD ostream& str) const;
1218#endif
1219 virtual bool Write(wxString& str) const;
1220#if wxUSE_STD_IOSTREAM
1221 virtual bool Read(wxSTD istream& str);
1222#endif
1223 virtual bool Read(wxString& str);
47b378bd 1224 virtual wxString GetType() const { return wxT("datetime"); }
c8058a09 1225 virtual wxVariantData* Clone() const { return new wxVariantDataDateTime(m_value); }
fb42d7c3
VZ
1226
1227protected:
2562c823 1228 wxDateTime m_value;
fb42d7c3
VZ
1229};
1230
fb42d7c3 1231
2562c823 1232bool wxVariantDataDateTime::Eq(wxVariantData& data) const
fb42d7c3 1233{
2562c823 1234 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
fb42d7c3 1235
2562c823 1236 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
fb42d7c3 1237
2562c823 1238 return (otherData.m_value == m_value);
fb42d7c3
VZ
1239}
1240
1241
1242#if wxUSE_STD_IOSTREAM
2562c823 1243bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
fb42d7c3 1244{
2562c823
RR
1245 wxString value;
1246 Write( value );
1247 str << value.c_str();
1248 return true;
fb42d7c3
VZ
1249}
1250#endif
1251
1252
2562c823 1253bool wxVariantDataDateTime::Write(wxString& str) const
fb42d7c3 1254{
2562c823 1255 str = m_value.Format();
cab1a605 1256 return true;
fb42d7c3
VZ
1257}
1258
1259
1260#if wxUSE_STD_IOSTREAM
2562c823 1261bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
fb42d7c3
VZ
1262{
1263 // Not implemented
cab1a605 1264 return false;
fb42d7c3
VZ
1265}
1266#endif
1267
1268
2562c823 1269bool wxVariantDataDateTime::Read(wxString& str)
fb42d7c3 1270{
52de37c7 1271 if(! m_value.ParseDateTime(str.c_str()/*FIXME-UTF8*/))
2562c823 1272 return false;
cab1a605 1273 return true;
fb42d7c3
VZ
1274}
1275
2562c823 1276// wxVariant
fb42d7c3 1277
ff818ab8
RG
1278wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1279{
cab1a605
WS
1280 m_data = new wxVariantDataDateTime(val);
1281 m_name = name;
ff818ab8 1282}
ff818ab8 1283
edca7a82
GT
1284#if wxUSE_ODBC
1285wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1286{
1287 m_data = new wxVariantDataDateTime(valptr);
1288 m_name = name;
1289}
1290
1291wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1292{
1293 m_data = new wxVariantDataDateTime(valptr);
1294 m_name = name;
1295}
1296
1297wxVariant::wxVariant(const DATE_STRUCT* valptr, const wxString& name) // Date
1298{
1299 m_data = new wxVariantDataDateTime(valptr);
1300 m_name = name;
1301}
fb42d7c3
VZ
1302#endif // wxUSE_ODBC
1303
2562c823 1304bool wxVariant::operator== (const wxDateTime& value) const
fb42d7c3 1305{
2562c823
RR
1306 wxDateTime thisValue;
1307 if (!Convert(&thisValue))
1308 return false;
1309
1310 return value.IsEqualTo(thisValue);
fb42d7c3 1311}
edca7a82 1312
2562c823 1313bool wxVariant::operator!= (const wxDateTime& value) const
341287bf 1314{
2562c823
RR
1315 return (!((*this) == value));
1316}
1317
1318void wxVariant::operator= (const wxDateTime& value)
1319{
1320 if (GetType() == wxT("datetime") &&
1321 m_data->GetRefCount() == 1)
341287bf 1322 {
2562c823 1323 ((wxVariantDataDateTime*)GetData())->SetValue(value);
341287bf 1324 }
4fabb575 1325 else
2562c823
RR
1326 {
1327 UnRef();
1328 m_data = new wxVariantDataDateTime(value);
1329 }
341287bf
JS
1330}
1331
2562c823
RR
1332#if wxUSE_ODBC
1333void wxVariant::operator= (const DATE_STRUCT* value)
341287bf 1334{
2562c823
RR
1335 UnRef();
1336 m_data = new wxVariantDataDateTime(value);
341287bf
JS
1337}
1338
2562c823 1339void wxVariant::operator= (const TIME_STRUCT* value)
341287bf 1340{
2562c823
RR
1341 UnRef();
1342 m_data = new wxVariantDataDateTime(value);
341287bf
JS
1343}
1344
2562c823 1345void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
341287bf 1346{
2562c823
RR
1347 UnRef();
1348 m_data = new wxVariantDataDateTime(value);
341287bf
JS
1349}
1350
2562c823 1351#endif // wxUSE_ODBC
341287bf 1352
2562c823
RR
1353wxDateTime wxVariant::GetDateTime() const
1354{
1355 wxDateTime value;
1356 if (!Convert(& value))
341287bf 1357 {
2562c823 1358 wxFAIL_MSG(wxT("Could not convert to a datetime"));
341287bf 1359 }
3d8daa0f 1360
2562c823 1361 return value;
341287bf
JS
1362}
1363
2562c823 1364#endif // wxUSE_DATETIME
341287bf 1365
2562c823
RR
1366// ----------------------------------------------------------------------------
1367// wxVariantDataArrayString
1368// ----------------------------------------------------------------------------
1369
1370class wxVariantDataArrayString: public wxVariantData
341287bf 1371{
2562c823
RR
1372public:
1373 wxVariantDataArrayString() { }
1374 wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
341287bf 1375
2562c823
RR
1376 wxArrayString GetValue() const { return m_value; }
1377 void SetValue(const wxArrayString& value) { m_value = value; }
341287bf 1378
2562c823
RR
1379 virtual bool Eq(wxVariantData& data) const;
1380#if wxUSE_STD_IOSTREAM
1381 virtual bool Write(wxSTD ostream& str) const;
1382#endif
1383 virtual bool Write(wxString& str) const;
1384#if wxUSE_STD_IOSTREAM
1385 virtual bool Read(wxSTD istream& str);
1386#endif
1387 virtual bool Read(wxString& str);
47b378bd 1388 virtual wxString GetType() const { return wxT("arrstring"); }
c8058a09 1389 virtual wxVariantData* Clone() const { return new wxVariantDataArrayString(m_value); }
341287bf 1390
2562c823
RR
1391protected:
1392 wxArrayString m_value;
2562c823 1393};
bc14c8b2 1394
2562c823 1395bool wxVariantDataArrayString::Eq(wxVariantData& data) const
341287bf 1396{
2562c823 1397 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
341287bf 1398
2562c823 1399 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
341287bf 1400
2562c823 1401 return otherData.m_value == m_value;
341287bf
JS
1402}
1403
2562c823
RR
1404#if wxUSE_STD_IOSTREAM
1405bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
341287bf 1406{
2562c823
RR
1407 // Not implemented
1408 return false;
341287bf 1409}
2562c823 1410#endif
341287bf 1411
2562c823 1412bool wxVariantDataArrayString::Write(wxString& str) const
341287bf 1413{
2562c823
RR
1414 size_t count = m_value.GetCount();
1415 for ( size_t n = 0; n < count; n++ )
341287bf 1416 {
2562c823
RR
1417 if ( n )
1418 str += _T(';');
1419
1420 str += m_value[n];
341287bf 1421 }
341287bf 1422
2562c823 1423 return true;
341287bf
JS
1424}
1425
2562c823
RR
1426
1427#if wxUSE_STD_IOSTREAM
1428bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
341287bf 1429{
2562c823
RR
1430 // Not implemented
1431 return false;
341287bf 1432}
2562c823 1433#endif
341287bf 1434
2562c823
RR
1435
1436bool wxVariantDataArrayString::Read(wxString& str)
341287bf 1437{
2562c823
RR
1438 wxStringTokenizer tk(str, _T(";"));
1439 while ( tk.HasMoreTokens() )
341287bf 1440 {
2562c823 1441 m_value.Add(tk.GetNextToken());
341287bf 1442 }
341287bf 1443
2562c823 1444 return true;
341287bf
JS
1445}
1446
2562c823
RR
1447// wxVariant
1448
1449wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1450{
1451 m_data = new wxVariantDataArrayString(val);
1452 m_name = name;
341287bf
JS
1453}
1454
2562c823 1455bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
341287bf 1456{
2562c823 1457 wxFAIL_MSG( _T("TODO") );
f6bcfd97 1458
2562c823 1459 return false;
341287bf
JS
1460}
1461
2562c823 1462bool wxVariant::operator!=(const wxArrayString& value) const
341287bf 1463{
2562c823 1464 return !(*this == value);
341287bf
JS
1465}
1466
2562c823 1467void wxVariant::operator=(const wxArrayString& value)
341287bf 1468{
2562c823
RR
1469 if (GetType() == wxT("arrstring") &&
1470 m_data->GetRefCount() == 1)
341287bf 1471 {
2562c823 1472 ((wxVariantDataArrayString *)GetData())->SetValue(value);
341287bf
JS
1473 }
1474 else
1475 {
2562c823
RR
1476 UnRef();
1477 m_data = new wxVariantDataArrayString(value);
341287bf
JS
1478 }
1479}
1480
2562c823 1481wxArrayString wxVariant::GetArrayString() const
341287bf 1482{
2562c823
RR
1483 if ( GetType() == wxT("arrstring") )
1484 return ((wxVariantDataArrayString *)GetData())->GetValue();
1485
1486 return wxArrayString();
341287bf
JS
1487}
1488
2562c823
RR
1489// ----------------------------------------------------------------------------
1490// wxVariantDataList
1491// ----------------------------------------------------------------------------
2c3a1064 1492
2562c823 1493class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
341287bf 1494{
2562c823
RR
1495public:
1496 wxVariantDataList() {}
9a0a58f5 1497 wxVariantDataList(const wxVariantList& list);
2562c823 1498 virtual ~wxVariantDataList();
341287bf 1499
9a0a58f5
RR
1500 wxVariantList& GetValue() { return m_value; }
1501 void SetValue(const wxVariantList& value) ;
341287bf 1502
2562c823
RR
1503 virtual bool Eq(wxVariantData& data) const;
1504#if wxUSE_STD_IOSTREAM
1505 virtual bool Write(wxSTD ostream& str) const;
1506#endif
1507 virtual bool Write(wxString& str) const;
1508#if wxUSE_STD_IOSTREAM
1509 virtual bool Read(wxSTD istream& str);
1510#endif
1511 virtual bool Read(wxString& str);
47b378bd 1512 virtual wxString GetType() const { return wxT("list"); }
52e81242 1513
2562c823 1514 void Clear();
341287bf 1515
c8058a09 1516 wxVariantData* Clone() const { return new wxVariantDataList(m_value); }
2562c823 1517protected:
9a0a58f5 1518 wxVariantList m_value;
2562c823 1519};
341287bf 1520
9a0a58f5 1521wxVariantDataList::wxVariantDataList(const wxVariantList& list)
341287bf 1522{
2562c823 1523 SetValue(list);
341287bf
JS
1524}
1525
2562c823 1526wxVariantDataList::~wxVariantDataList()
341287bf 1527{
2562c823 1528 Clear();
341287bf
JS
1529}
1530
9a0a58f5 1531void wxVariantDataList::SetValue(const wxVariantList& value)
341287bf 1532{
2562c823 1533 Clear();
9a0a58f5 1534 wxVariantList::compatibility_iterator node = value.GetFirst();
2562c823 1535 while (node)
341287bf 1536 {
9a0a58f5 1537 wxVariant* var = node->GetData();
2562c823
RR
1538 m_value.Append(new wxVariant(*var));
1539 node = node->GetNext();
341287bf 1540 }
2562c823
RR
1541}
1542
1543void wxVariantDataList::Clear()
1544{
9a0a58f5 1545 wxVariantList::compatibility_iterator node = m_value.GetFirst();
2562c823 1546 while (node)
341287bf 1547 {
9a0a58f5 1548 wxVariant* var = node->GetData();
2562c823
RR
1549 delete var;
1550 node = node->GetNext();
341287bf 1551 }
2562c823 1552 m_value.Clear();
341287bf
JS
1553}
1554
2562c823 1555bool wxVariantDataList::Eq(wxVariantData& data) const
a0a302dc 1556{
2562c823
RR
1557 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
1558
1559 wxVariantDataList& listData = (wxVariantDataList&) data;
9a0a58f5
RR
1560 wxVariantList::compatibility_iterator node1 = m_value.GetFirst();
1561 wxVariantList::compatibility_iterator node2 = listData.GetValue().GetFirst();
2562c823
RR
1562 while (node1 && node2)
1563 {
9a0a58f5
RR
1564 wxVariant* var1 = node1->GetData();
1565 wxVariant* var2 = node2->GetData();
2562c823
RR
1566 if ((*var1) != (*var2))
1567 return false;
1568 node1 = node1->GetNext();
1569 node2 = node2->GetNext();
1570 }
1571 if (node1 || node2) return false;
1572 return true;
a0a302dc
JS
1573}
1574
2562c823
RR
1575#if wxUSE_STD_IOSTREAM
1576bool wxVariantDataList::Write(wxSTD ostream& str) const
a0a302dc 1577{
2562c823
RR
1578 wxString s;
1579 Write(s);
1580 str << (const char*) s.mb_str();
1581 return true;
a0a302dc 1582}
2562c823 1583#endif
a0a302dc 1584
2562c823 1585bool wxVariantDataList::Write(wxString& str) const
a0a302dc 1586{
2562c823 1587 str = wxEmptyString;
9a0a58f5 1588 wxVariantList::compatibility_iterator node = m_value.GetFirst();
2562c823 1589 while (node)
a0a302dc 1590 {
9a0a58f5 1591 wxVariant* var = node->GetData();
2562c823
RR
1592 if (node != m_value.GetFirst())
1593 str += wxT(" ");
1594 wxString str1;
1595 str += var->MakeString();
1596 node = node->GetNext();
a0a302dc 1597 }
2562c823
RR
1598
1599 return true;
a0a302dc 1600}
2f620946 1601
2562c823
RR
1602#if wxUSE_STD_IOSTREAM
1603bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
2f620946 1604{
2562c823
RR
1605 wxFAIL_MSG(wxT("Unimplemented"));
1606 // TODO
1607 return false;
2f620946 1608}
2562c823 1609#endif
2f620946 1610
2562c823 1611bool wxVariantDataList::Read(wxString& WXUNUSED(str))
2f620946 1612{
2562c823
RR
1613 wxFAIL_MSG(wxT("Unimplemented"));
1614 // TODO
1615 return false;
2f620946
RR
1616}
1617
2562c823
RR
1618// wxVariant
1619
9a0a58f5 1620wxVariant::wxVariant(const wxVariantList& val, const wxString& name) // List of variants
2f620946 1621{
2562c823
RR
1622 m_data = new wxVariantDataList(val);
1623 m_name = name;
2f620946 1624}
341287bf 1625
9a0a58f5 1626bool wxVariant::operator== (const wxVariantList& value) const
edca7a82 1627{
2562c823 1628 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
edca7a82 1629
2562c823
RR
1630 wxVariantDataList other(value);
1631 return (GetData()->Eq(other));
edca7a82
GT
1632}
1633
9a0a58f5 1634bool wxVariant::operator!= (const wxVariantList& value) const
edca7a82
GT
1635{
1636 return (!((*this) == value));
1637}
1638
9a0a58f5 1639void wxVariant::operator= (const wxVariantList& value)
edca7a82 1640{
2562c823
RR
1641 if (GetType() == wxT("list") &&
1642 m_data->GetRefCount() == 1)
edca7a82 1643 {
2562c823 1644 ((wxVariantDataList*)GetData())->SetValue(value);
edca7a82
GT
1645 }
1646 else
1647 {
2562c823
RR
1648 UnRef();
1649 m_data = new wxVariantDataList(value);
edca7a82
GT
1650 }
1651}
1652
9a0a58f5 1653wxVariantList& wxVariant::GetList() const
edca7a82 1654{
2562c823 1655 wxASSERT( (GetType() == wxT("list")) );
edca7a82 1656
9a0a58f5 1657 return (wxVariantList&) ((wxVariantDataList*) m_data)->GetValue();
2562c823 1658}
edca7a82 1659
2562c823
RR
1660// Make empty list
1661void wxVariant::NullList()
edca7a82 1662{
2562c823 1663 SetData(new wxVariantDataList());
edca7a82
GT
1664}
1665
2562c823
RR
1666// Append to list
1667void wxVariant::Append(const wxVariant& value)
edca7a82 1668{
9a0a58f5 1669 wxVariantList& list = GetList();
2562c823
RR
1670
1671 list.Append(new wxVariant(value));
edca7a82
GT
1672}
1673
2562c823
RR
1674// Insert at front of list
1675void wxVariant::Insert(const wxVariant& value)
1676{
9a0a58f5 1677 wxVariantList& list = GetList();
fb42d7c3 1678
2562c823
RR
1679 list.Insert(new wxVariant(value));
1680}
1681
1682// Returns true if the variant is a member of the list
1683bool wxVariant::Member(const wxVariant& value) const
fb42d7c3 1684{
9a0a58f5 1685 wxVariantList& list = GetList();
fb42d7c3 1686
9a0a58f5 1687 wxVariantList::compatibility_iterator node = list.GetFirst();
2562c823
RR
1688 while (node)
1689 {
9a0a58f5 1690 wxVariant* other = node->GetData();
2562c823
RR
1691 if (value == *other)
1692 return true;
1693 node = node->GetNext();
1694 }
cab1a605 1695 return false;
fb42d7c3
VZ
1696}
1697
2562c823
RR
1698// Deletes the nth element of the list
1699bool wxVariant::Delete(size_t item)
fb42d7c3 1700{
9a0a58f5 1701 wxVariantList& list = GetList();
2562c823
RR
1702
1703 wxASSERT_MSG( (item < list.GetCount()), wxT("Invalid index to Delete") );
9a0a58f5
RR
1704 wxVariantList::compatibility_iterator node = list.Item(item);
1705 wxVariant* variant = node->GetData();
2562c823
RR
1706 delete variant;
1707 list.Erase(node);
1708 return true;
fb42d7c3
VZ
1709}
1710
2562c823
RR
1711// Clear list
1712void wxVariant::ClearList()
fb42d7c3 1713{
2562c823 1714 if (!IsNull() && (GetType() == wxT("list")))
fb42d7c3 1715 {
2562c823 1716 ((wxVariantDataList*) m_data)->Clear();
fb42d7c3
VZ
1717 }
1718 else
1719 {
2562c823
RR
1720 if (!GetType().IsSameAs(wxT("list")))
1721 UnRef();
fb42d7c3 1722
2562c823
RR
1723 m_data = new wxVariantDataList;
1724 }
fb42d7c3
VZ
1725}
1726
60acae80
RR
1727// Treat a list variant as an array
1728wxVariant wxVariant::operator[] (size_t idx) const
1729{
60acae80 1730 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
60acae80
RR
1731
1732 if (GetType() == wxT("list"))
1733 {
1734 wxVariantDataList* data = (wxVariantDataList*) m_data;
1735 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
9a0a58f5 1736 return *(data->GetValue().Item(idx)->GetData());
60acae80 1737 }
60acae80
RR
1738 return wxNullVariant;
1739}
1740
1741wxVariant& wxVariant::operator[] (size_t idx)
1742{
1743 // We can't return a reference to a variant for a string list, since the string
1744 // is actually stored as a char*, not a variant.
1745
1746 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1747
1748 wxVariantDataList* data = (wxVariantDataList*) m_data;
1749 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1750
9a0a58f5 1751 return * (data->GetValue().Item(idx)->GetData());
60acae80
RR
1752}
1753
1754// Return the number of elements in a list
1755size_t wxVariant::GetCount() const
1756{
60acae80 1757 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
60acae80
RR
1758
1759 if (GetType() == wxT("list"))
1760 {
1761 wxVariantDataList* data = (wxVariantDataList*) m_data;
1762 return data->GetValue().GetCount();
1763 }
60acae80
RR
1764 return 0;
1765}
1766
2562c823 1767// ----------------------------------------------------------------------------
341287bf 1768// Type conversion
2562c823
RR
1769// ----------------------------------------------------------------------------
1770
341287bf
JS
1771bool wxVariant::Convert(long* value) const
1772{
1773 wxString type(GetType());
223d09f6 1774 if (type == wxT("double"))
2562c823 1775 *value = (long) (((wxVariantDoubleData*)GetData())->GetValue());
223d09f6 1776 else if (type == wxT("long"))
341287bf 1777 *value = ((wxVariantDataLong*)GetData())->GetValue();
862416e0 1778#ifdef HAVE_BOOL
223d09f6 1779 else if (type == wxT("bool"))
341287bf 1780 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1781#endif
223d09f6 1782 else if (type == wxT("string"))
52de37c7 1783 *value = wxAtol(((wxVariantDataString*)GetData())->GetValue());
341287bf 1784 else
cab1a605 1785 return false;
341287bf 1786
cab1a605 1787 return true;
341287bf
JS
1788}
1789
1790bool wxVariant::Convert(bool* value) const
1791{
1792 wxString type(GetType());
223d09f6 1793 if (type == wxT("double"))
2562c823 1794 *value = ((int) (((wxVariantDoubleData*)GetData())->GetValue()) != 0);
223d09f6 1795 else if (type == wxT("long"))
341287bf 1796 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
862416e0 1797#ifdef HAVE_BOOL
223d09f6 1798 else if (type == wxT("bool"))
341287bf 1799 *value = ((wxVariantDataBool*)GetData())->GetValue();
862416e0 1800#endif
223d09f6 1801 else if (type == wxT("string"))
341287bf
JS
1802 {
1803 wxString val(((wxVariantDataString*)GetData())->GetValue());
1804 val.MakeLower();
b1638abf 1805 if (val == wxT("true") || val == wxT("yes") || val == wxT('1') )
cab1a605 1806 *value = true;
b1638abf 1807 else if (val == wxT("false") || val == wxT("no") || val == wxT('0') )
cab1a605 1808 *value = false;
341287bf 1809 else
cab1a605 1810 return false;
341287bf
JS
1811 }
1812 else
cab1a605 1813 return false;
341287bf 1814
cab1a605 1815 return true;
341287bf
JS
1816}
1817
1818bool wxVariant::Convert(double* value) const
1819{
1820 wxString type(GetType());
223d09f6 1821 if (type == wxT("double"))
2562c823 1822 *value = ((wxVariantDoubleData*)GetData())->GetValue();
223d09f6 1823 else if (type == wxT("long"))
341287bf 1824 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
862416e0 1825#ifdef HAVE_BOOL
223d09f6 1826 else if (type == wxT("bool"))
341287bf 1827 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1828#endif
223d09f6 1829 else if (type == wxT("string"))
52de37c7 1830 *value = (double) wxAtof(((wxVariantDataString*)GetData())->GetValue());
341287bf 1831 else
cab1a605 1832 return false;
341287bf 1833
cab1a605 1834 return true;
341287bf
JS
1835}
1836
af717fa8 1837bool wxVariant::Convert(wxUniChar* value) const
341287bf
JS
1838{
1839 wxString type(GetType());
223d09f6 1840 if (type == wxT("char"))
341287bf 1841 *value = ((wxVariantDataChar*)GetData())->GetValue();
223d09f6 1842 else if (type == wxT("long"))
341287bf 1843 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
862416e0 1844#ifdef HAVE_BOOL
223d09f6 1845 else if (type == wxT("bool"))
341287bf 1846 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1847#endif
341287bf 1848 else
cab1a605 1849 return false;
341287bf 1850
cab1a605 1851 return true;
341287bf
JS
1852}
1853
af717fa8
VS
1854bool wxVariant::Convert(char* value) const
1855{
1856 wxUniChar ch;
1857 if ( !Convert(&ch) )
1858 return false;
1859 *value = ch;
1860 return true;
1861}
1862
1863bool wxVariant::Convert(wchar_t* value) const
1864{
1865 wxUniChar ch;
1866 if ( !Convert(&ch) )
1867 return false;
1868 *value = ch;
1869 return true;
1870}
1871
341287bf
JS
1872bool wxVariant::Convert(wxString* value) const
1873{
1874 *value = MakeString();
cab1a605 1875 return true;
341287bf
JS
1876}
1877
e2b87f38 1878#if wxUSE_DATETIME
edca7a82
GT
1879bool wxVariant::Convert(wxDateTime* value) const
1880{
1881 wxString type(GetType());
1882 if (type == wxT("datetime"))
9708db20 1883 {
edca7a82 1884 *value = ((wxVariantDataDateTime*)GetData())->GetValue();
cab1a605 1885 return true;
dc259b79 1886 }
9708db20
JS
1887 // Fallback to string conversion
1888 wxString val;
9a8a9e99 1889 return Convert(&val) &&
52de37c7
VS
1890 (value->ParseDateTime(val.c_str()/*FIXME-UTF8*/) ||
1891 value->ParseDate(val.c_str()/*FIXME-UTF8*/) ||
1892 value->ParseTime(val.c_str()/*FIXME-UTF8*/));
edca7a82 1893}
b1e343f2 1894#endif // wxUSE_DATETIME
d5dc103f
VZ
1895
1896#endif // wxUSE_VARIANT