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