]> git.saurik.com Git - wxWidgets.git/blame - src/common/variant.cpp
Update OpenVMS compile support
[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
153107b4
JS
882#if wxUSE_ANY
883// This allows converting string literal wxAnys to string variants
884wxVariantData* wxVariantDataFromConstCharPAny(const wxAny& any)
885{
886 return new wxVariantDataString(wxANY_AS(any, const char*));
887}
888
889wxVariantData* wxVariantDataFromConstWchar_tPAny(const wxAny& any)
890{
891 return new wxVariantDataString(wxANY_AS(any, const wchar_t*));
892}
893
894_REGISTER_WXANY_CONVERSION(const char*,
895 ConstCharP,
896 wxVariantDataFromConstCharPAny)
897_REGISTER_WXANY_CONVERSION(const wchar_t*,
898 ConstWchar_tP,
899 wxVariantDataFromConstWchar_tPAny)
900#endif
901
341287bf
JS
902bool wxVariantDataString::Eq(wxVariantData& data) const
903{
223d09f6 904 wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
341287bf
JS
905
906 wxVariantDataString& otherData = (wxVariantDataString&) data;
907
908 return (otherData.m_value == m_value);
909}
910
38830220 911#if wxUSE_STD_IOSTREAM
dd107c50 912bool wxVariantDataString::Write(wxSTD ostream& str) const
341287bf 913{
783b6cfd 914 str << (const char*) m_value.mb_str();
cab1a605 915 return true;
341287bf 916}
38830220 917#endif
341287bf
JS
918
919bool wxVariantDataString::Write(wxString& str) const
920{
921 str = m_value;
cab1a605 922 return true;
341287bf
JS
923}
924
e02afc7a 925#if wxUSE_STREAMS
1ccbb61a
VZ
926bool wxVariantDataString::Write(wxOutputStream& str) const
927{
783b6cfd 928 // why doesn't wxOutputStream::operator<< take "const wxString&"
fae05df5
GL
929 wxTextOutputStream s(str);
930 s.WriteString(m_value);
cab1a605 931 return true;
1ccbb61a
VZ
932}
933
75ed1d15
GL
934bool wxVariantDataString::Read(wxInputStream& str)
935{
fae05df5
GL
936 wxTextInputStream s(str);
937
40ff126a 938 m_value = s.ReadLine();
cab1a605 939 return true;
75ed1d15 940}
e02afc7a 941#endif // wxUSE_STREAMS
75ed1d15 942
341287bf
JS
943bool wxVariantDataString::Read(wxString& str)
944{
945 m_value = str;
cab1a605 946 return true;
341287bf
JS
947}
948
2562c823 949// wxVariant ****
07502d73 950
2562c823 951wxVariant::wxVariant(const wxString& val, const wxString& name)
a0a302dc 952{
cf25a599 953 m_refData = new wxVariantDataString(val);
2562c823
RR
954 m_name = name;
955}
a0a302dc 956
af717fa8
VS
957wxVariant::wxVariant(const char* val, const wxString& name)
958{
cf25a599 959 m_refData = new wxVariantDataString(wxString(val));
af717fa8
VS
960 m_name = name;
961}
962
963wxVariant::wxVariant(const wchar_t* val, const wxString& name)
964{
cf25a599 965 m_refData = new wxVariantDataString(wxString(val));
af717fa8
VS
966 m_name = name;
967}
968
969wxVariant::wxVariant(const wxCStrData& val, const wxString& name)
970{
cf25a599 971 m_refData = new wxVariantDataString(val.AsString());
af717fa8
VS
972 m_name = name;
973}
974
de4983f3 975wxVariant::wxVariant(const wxScopedCharBuffer& val, const wxString& name)
af717fa8 976{
cf25a599 977 m_refData = new wxVariantDataString(wxString(val));
af717fa8
VS
978 m_name = name;
979}
980
de4983f3 981wxVariant::wxVariant(const wxScopedWCharBuffer& val, const wxString& name)
a0a302dc 982{
cf25a599 983 m_refData = new wxVariantDataString(wxString(val));
2562c823
RR
984 m_name = name;
985}
a0a302dc 986
2562c823
RR
987bool wxVariant::operator== (const wxString& value) const
988{
989 wxString thisValue;
990 if (!Convert(&thisValue))
991 return false;
a0a302dc 992
2562c823 993 return value == thisValue;
a0a302dc
JS
994}
995
2562c823 996bool wxVariant::operator!= (const wxString& value) const
a0a302dc 997{
2562c823 998 return (!((*this) == value));
a0a302dc
JS
999}
1000
af717fa8 1001wxVariant& wxVariant::operator= (const wxString& value)
a0a302dc 1002{
2562c823 1003 if (GetType() == wxT("string") &&
cf25a599 1004 m_refData->GetRefCount() == 1)
2562c823
RR
1005 {
1006 ((wxVariantDataString*)GetData())->SetValue(value);
1007 }
1008 else
1009 {
1010 UnRef();
cf25a599 1011 m_refData = new wxVariantDataString(value);
2562c823 1012 }
af717fa8 1013 return *this;
a0a302dc
JS
1014}
1015
2562c823 1016wxString wxVariant::GetString() const
a0a302dc 1017{
2562c823
RR
1018 wxString value;
1019 if (!Convert(& value))
1020 {
1021 wxFAIL_MSG(wxT("Could not convert to a string"));
1022 }
a0a302dc 1023
2562c823 1024 return value;
a0a302dc
JS
1025}
1026
2562c823
RR
1027// ----------------------------------------------------------------------------
1028// wxVariantDataWxObjectPtr
1029// ----------------------------------------------------------------------------
cf6ae290
RG
1030
1031class wxVariantDataWxObjectPtr: public wxVariantData
1032{
cf6ae290
RG
1033public:
1034 wxVariantDataWxObjectPtr() { }
1035 wxVariantDataWxObjectPtr(wxObject* value) { m_value = value; }
1036
1037 inline wxObject* GetValue() const { return m_value; }
1038 inline void SetValue(wxObject* value) { m_value = value; }
1039
cf6ae290
RG
1040 virtual bool Eq(wxVariantData& data) const;
1041#if wxUSE_STD_IOSTREAM
1042 virtual bool Write(wxSTD ostream& str) const;
1043#endif
1044 virtual bool Write(wxString& str) const;
1045#if wxUSE_STD_IOSTREAM
1046 virtual bool Read(wxSTD istream& str);
1047#endif
1048 virtual bool Read(wxString& str);
1049 virtual wxString GetType() const ;
c8058a09 1050 virtual wxVariantData* Clone() const { return new wxVariantDataWxObjectPtr(m_value); }
cf6ae290 1051
3586d10f 1052 virtual wxClassInfo* GetValueClassInfo();
c8058a09 1053
0bf14ab8 1054 DECLARE_WXANY_CONVERSION()
cf6ae290
RG
1055protected:
1056 wxObject* m_value;
cf6ae290
RG
1057};
1058
0bf14ab8
JS
1059IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxObject*, wxVariantDataWxObjectPtr)
1060
cf6ae290
RG
1061bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const
1062{
3586d10f 1063 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
cf6ae290
RG
1064
1065 wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
1066
1067 return (otherData.m_value == m_value);
1068}
1069
1070wxString wxVariantDataWxObjectPtr::GetType() const
1071{
3586d10f 1072 wxString returnVal(wxT("wxObject*"));
c8058a09 1073
3586d10f
RR
1074 if (m_value)
1075 {
cf6ae290 1076 returnVal = m_value->GetClassInfo()->GetClassName();
3586d10f 1077 returnVal += wxT("*");
cf6ae290 1078 }
c8058a09 1079
cf6ae290
RG
1080 return returnVal;
1081}
1082
1083wxClassInfo* wxVariantDataWxObjectPtr::GetValueClassInfo()
1084{
1085 wxClassInfo* returnVal=NULL;
cab1a605
WS
1086
1087 if (m_value) returnVal = m_value->GetClassInfo();
cf6ae290
RG
1088
1089 return returnVal;
1090}
1091
1092#if wxUSE_STD_IOSTREAM
1093bool wxVariantDataWxObjectPtr::Write(wxSTD ostream& str) const
1094{
1095 wxString s;
1096 Write(s);
1097 str << (const char*) s.mb_str();
cab1a605 1098 return true;
cf6ae290
RG
1099}
1100#endif
1101
1102bool wxVariantDataWxObjectPtr::Write(wxString& str) const
1103{
5c33522f 1104 str.Printf(wxT("%s(%p)"), GetType().c_str(), static_cast<void*>(m_value));
cab1a605 1105 return true;
cf6ae290
RG
1106}
1107
1108#if wxUSE_STD_IOSTREAM
1109bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
1110{
1111 // Not implemented
cab1a605 1112 return false;
cf6ae290
RG
1113}
1114#endif
1115
1116bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
1117{
1118 // Not implemented
cab1a605 1119 return false;
cf6ae290
RG
1120}
1121
2562c823 1122// wxVariant
cf6ae290 1123
2562c823
RR
1124wxVariant::wxVariant( wxObject* val, const wxString& name)
1125{
cf25a599 1126 m_refData = new wxVariantDataWxObjectPtr(val);
2562c823
RR
1127 m_name = name;
1128}
edca7a82 1129
2562c823
RR
1130bool wxVariant::operator== (wxObject* value) const
1131{
1132 return (value == ((wxVariantDataWxObjectPtr*)GetData())->GetValue());
1133}
e2b87f38 1134
2562c823 1135bool wxVariant::operator!= (wxObject* value) const
edca7a82 1136{
2562c823
RR
1137 return (!((*this) == (wxObject*) value));
1138}
1139
1140void wxVariant::operator= (wxObject* value)
1141{
1142 UnRef();
cf25a599 1143 m_refData = new wxVariantDataWxObjectPtr(value);
2562c823 1144}
edca7a82 1145
2562c823
RR
1146wxObject* wxVariant::GetWxObjectPtr() const
1147{
cf25a599 1148 return (wxObject*) ((wxVariantDataWxObjectPtr*) m_refData)->GetValue();
2562c823
RR
1149}
1150
1151// ----------------------------------------------------------------------------
1152// wxVariantDataVoidPtr
1153// ----------------------------------------------------------------------------
1154
1155class wxVariantDataVoidPtr: public wxVariantData
1156{
edca7a82 1157public:
2562c823
RR
1158 wxVariantDataVoidPtr() { }
1159 wxVariantDataVoidPtr(void* value) { m_value = value; }
edca7a82 1160
2562c823
RR
1161 inline void* GetValue() const { return m_value; }
1162 inline void SetValue(void* value) { m_value = value; }
edca7a82 1163
edca7a82
GT
1164 virtual bool Eq(wxVariantData& data) const;
1165#if wxUSE_STD_IOSTREAM
2b004197 1166 virtual bool Write(wxSTD ostream& str) const;
edca7a82
GT
1167#endif
1168 virtual bool Write(wxString& str) const;
1169#if wxUSE_STD_IOSTREAM
2b004197 1170 virtual bool Read(wxSTD istream& str);
edca7a82
GT
1171#endif
1172 virtual bool Read(wxString& str);
47b378bd 1173 virtual wxString GetType() const { return wxT("void*"); }
c8058a09 1174 virtual wxVariantData* Clone() const { return new wxVariantDataVoidPtr(m_value); }
edca7a82 1175
0bf14ab8 1176 DECLARE_WXANY_CONVERSION()
edca7a82 1177protected:
2562c823 1178 void* m_value;
2562c823 1179};
edca7a82 1180
0bf14ab8
JS
1181IMPLEMENT_TRIVIAL_WXANY_CONVERSION(void*, wxVariantDataVoidPtr)
1182
2562c823 1183bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
edca7a82 1184{
3586d10f 1185 wxASSERT_MSG( data.GetType() == wxT("void*"), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
edca7a82 1186
2562c823 1187 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
edca7a82 1188
2562c823 1189 return (otherData.m_value == m_value);
edca7a82
GT
1190}
1191
2562c823
RR
1192#if wxUSE_STD_IOSTREAM
1193bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
edca7a82 1194{
2562c823
RR
1195 wxString s;
1196 Write(s);
1197 str << (const char*) s.mb_str();
1198 return true;
edca7a82 1199}
2562c823 1200#endif
edca7a82 1201
2562c823
RR
1202bool wxVariantDataVoidPtr::Write(wxString& str) const
1203{
1204 str.Printf(wxT("%p"), m_value);
1205 return true;
1206}
edca7a82
GT
1207
1208#if wxUSE_STD_IOSTREAM
2562c823 1209bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
edca7a82
GT
1210{
1211 // Not implemented
cab1a605 1212 return false;
edca7a82
GT
1213}
1214#endif
1215
2562c823 1216bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
edca7a82 1217{
2562c823
RR
1218 // Not implemented
1219 return false;
edca7a82
GT
1220}
1221
2562c823 1222// wxVariant
edca7a82 1223
2562c823 1224wxVariant::wxVariant( void* val, const wxString& name)
edca7a82 1225{
cf25a599 1226 m_refData = new wxVariantDataVoidPtr(val);
2562c823
RR
1227 m_name = name;
1228}
1229
1230bool wxVariant::operator== (void* value) const
1231{
1232 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
edca7a82 1233}
edca7a82 1234
2562c823
RR
1235bool wxVariant::operator!= (void* value) const
1236{
1237 return (!((*this) == (void*) value));
1238}
edca7a82 1239
2562c823 1240void wxVariant::operator= (void* value)
edca7a82 1241{
cf25a599 1242 if (GetType() == wxT("void*") && (m_refData->GetRefCount() == 1))
2562c823
RR
1243 {
1244 ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1245 }
1246 else
1247 {
1248 UnRef();
cf25a599 1249 m_refData = new wxVariantDataVoidPtr(value);
2562c823 1250 }
edca7a82
GT
1251}
1252
2562c823
RR
1253void* wxVariant::GetVoidPtr() const
1254{
d099c754
VZ
1255 // handling this specially is convenient when working with COM, see #9873
1256 if ( IsNull() )
1257 return NULL;
1258
1259 wxASSERT( GetType() == wxT("void*") );
2562c823 1260
cf25a599 1261 return (void*) ((wxVariantDataVoidPtr*) m_refData)->GetValue();
2562c823 1262}
e2b87f38 1263
fb42d7c3 1264// ----------------------------------------------------------------------------
2562c823 1265// wxVariantDataDateTime
fb42d7c3
VZ
1266// ----------------------------------------------------------------------------
1267
2562c823
RR
1268#if wxUSE_DATETIME
1269
1270class wxVariantDataDateTime: public wxVariantData
fb42d7c3
VZ
1271{
1272public:
2562c823
RR
1273 wxVariantDataDateTime() { }
1274 wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
fb42d7c3 1275
2562c823
RR
1276 inline wxDateTime GetValue() const { return m_value; }
1277 inline void SetValue(const wxDateTime& value) { m_value = value; }
fb42d7c3 1278
fb42d7c3
VZ
1279 virtual bool Eq(wxVariantData& data) const;
1280#if wxUSE_STD_IOSTREAM
1281 virtual bool Write(wxSTD ostream& str) const;
1282#endif
1283 virtual bool Write(wxString& str) const;
1284#if wxUSE_STD_IOSTREAM
1285 virtual bool Read(wxSTD istream& str);
1286#endif
1287 virtual bool Read(wxString& str);
47b378bd 1288 virtual wxString GetType() const { return wxT("datetime"); }
c8058a09 1289 virtual wxVariantData* Clone() const { return new wxVariantDataDateTime(m_value); }
fb42d7c3 1290
0bf14ab8 1291 DECLARE_WXANY_CONVERSION()
fb42d7c3 1292protected:
2562c823 1293 wxDateTime m_value;
fb42d7c3
VZ
1294};
1295
0bf14ab8 1296IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxDateTime, wxVariantDataDateTime)
fb42d7c3 1297
2562c823 1298bool wxVariantDataDateTime::Eq(wxVariantData& data) const
fb42d7c3 1299{
2562c823 1300 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
fb42d7c3 1301
2562c823 1302 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
fb42d7c3 1303
2562c823 1304 return (otherData.m_value == m_value);
fb42d7c3
VZ
1305}
1306
1307
1308#if wxUSE_STD_IOSTREAM
2562c823 1309bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
fb42d7c3 1310{
2562c823
RR
1311 wxString value;
1312 Write( value );
1313 str << value.c_str();
1314 return true;
fb42d7c3
VZ
1315}
1316#endif
1317
1318
2562c823 1319bool wxVariantDataDateTime::Write(wxString& str) const
fb42d7c3 1320{
be53e8ae
JS
1321 if ( m_value.IsValid() )
1322 str = m_value.Format();
1323 else
1324 str = wxS("Invalid");
cab1a605 1325 return true;
fb42d7c3
VZ
1326}
1327
1328
1329#if wxUSE_STD_IOSTREAM
2562c823 1330bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
fb42d7c3
VZ
1331{
1332 // Not implemented
cab1a605 1333 return false;
fb42d7c3
VZ
1334}
1335#endif
1336
1337
2562c823 1338bool wxVariantDataDateTime::Read(wxString& str)
fb42d7c3 1339{
be53e8ae
JS
1340 if ( str == wxS("Invalid") )
1341 {
1342 m_value = wxInvalidDateTime;
1343 return true;
1344 }
1345
c398434d
VZ
1346 wxString::const_iterator end;
1347 return m_value.ParseDateTime(str, &end) && end == str.end();
fb42d7c3
VZ
1348}
1349
2562c823 1350// wxVariant
fb42d7c3 1351
ff818ab8
RG
1352wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1353{
cf25a599 1354 m_refData = new wxVariantDataDateTime(val);
cab1a605 1355 m_name = name;
ff818ab8 1356}
ff818ab8 1357
2562c823 1358bool wxVariant::operator== (const wxDateTime& value) const
fb42d7c3 1359{
2562c823
RR
1360 wxDateTime thisValue;
1361 if (!Convert(&thisValue))
1362 return false;
1363
1364 return value.IsEqualTo(thisValue);
fb42d7c3 1365}
edca7a82 1366
2562c823 1367bool wxVariant::operator!= (const wxDateTime& value) const
341287bf 1368{
2562c823
RR
1369 return (!((*this) == value));
1370}
1371
1372void wxVariant::operator= (const wxDateTime& value)
1373{
1374 if (GetType() == wxT("datetime") &&
cf25a599 1375 m_refData->GetRefCount() == 1)
341287bf 1376 {
2562c823 1377 ((wxVariantDataDateTime*)GetData())->SetValue(value);
341287bf 1378 }
4fabb575 1379 else
2562c823
RR
1380 {
1381 UnRef();
cf25a599 1382 m_refData = new wxVariantDataDateTime(value);
2562c823 1383 }
341287bf
JS
1384}
1385
2562c823
RR
1386wxDateTime wxVariant::GetDateTime() const
1387{
1388 wxDateTime value;
1389 if (!Convert(& value))
341287bf 1390 {
2562c823 1391 wxFAIL_MSG(wxT("Could not convert to a datetime"));
341287bf 1392 }
3d8daa0f 1393
2562c823 1394 return value;
341287bf
JS
1395}
1396
2562c823 1397#endif // wxUSE_DATETIME
341287bf 1398
2562c823
RR
1399// ----------------------------------------------------------------------------
1400// wxVariantDataArrayString
1401// ----------------------------------------------------------------------------
1402
1403class wxVariantDataArrayString: public wxVariantData
341287bf 1404{
2562c823
RR
1405public:
1406 wxVariantDataArrayString() { }
1407 wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
341287bf 1408
2562c823
RR
1409 wxArrayString GetValue() const { return m_value; }
1410 void SetValue(const wxArrayString& value) { m_value = value; }
341287bf 1411
2562c823
RR
1412 virtual bool Eq(wxVariantData& data) const;
1413#if wxUSE_STD_IOSTREAM
1414 virtual bool Write(wxSTD ostream& str) const;
1415#endif
1416 virtual bool Write(wxString& str) const;
1417#if wxUSE_STD_IOSTREAM
1418 virtual bool Read(wxSTD istream& str);
1419#endif
1420 virtual bool Read(wxString& str);
47b378bd 1421 virtual wxString GetType() const { return wxT("arrstring"); }
c8058a09 1422 virtual wxVariantData* Clone() const { return new wxVariantDataArrayString(m_value); }
341287bf 1423
0bf14ab8 1424 DECLARE_WXANY_CONVERSION()
2562c823
RR
1425protected:
1426 wxArrayString m_value;
2562c823 1427};
bc14c8b2 1428
0bf14ab8
JS
1429IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxArrayString, wxVariantDataArrayString)
1430
2562c823 1431bool wxVariantDataArrayString::Eq(wxVariantData& data) const
341287bf 1432{
2562c823 1433 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
341287bf 1434
2562c823 1435 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
341287bf 1436
2562c823 1437 return otherData.m_value == m_value;
341287bf
JS
1438}
1439
2562c823
RR
1440#if wxUSE_STD_IOSTREAM
1441bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
341287bf 1442{
2562c823
RR
1443 // Not implemented
1444 return false;
341287bf 1445}
2562c823 1446#endif
341287bf 1447
2562c823 1448bool wxVariantDataArrayString::Write(wxString& str) const
341287bf 1449{
2562c823
RR
1450 size_t count = m_value.GetCount();
1451 for ( size_t n = 0; n < count; n++ )
341287bf 1452 {
2562c823 1453 if ( n )
9a83f860 1454 str += wxT(';');
2562c823
RR
1455
1456 str += m_value[n];
341287bf 1457 }
341287bf 1458
2562c823 1459 return true;
341287bf
JS
1460}
1461
2562c823
RR
1462
1463#if wxUSE_STD_IOSTREAM
1464bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
341287bf 1465{
2562c823
RR
1466 // Not implemented
1467 return false;
341287bf 1468}
2562c823 1469#endif
341287bf 1470
2562c823
RR
1471
1472bool wxVariantDataArrayString::Read(wxString& str)
341287bf 1473{
9a83f860 1474 wxStringTokenizer tk(str, wxT(";"));
2562c823 1475 while ( tk.HasMoreTokens() )
341287bf 1476 {
2562c823 1477 m_value.Add(tk.GetNextToken());
341287bf 1478 }
341287bf 1479
2562c823 1480 return true;
341287bf
JS
1481}
1482
2562c823
RR
1483// wxVariant
1484
1485wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1486{
cf25a599 1487 m_refData = new wxVariantDataArrayString(val);
2562c823 1488 m_name = name;
341287bf
JS
1489}
1490
2562c823 1491bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
341287bf 1492{
9a83f860 1493 wxFAIL_MSG( wxT("TODO") );
f6bcfd97 1494
2562c823 1495 return false;
341287bf
JS
1496}
1497
2562c823 1498bool wxVariant::operator!=(const wxArrayString& value) const
341287bf 1499{
2562c823 1500 return !(*this == value);
341287bf
JS
1501}
1502
2562c823 1503void wxVariant::operator=(const wxArrayString& value)
341287bf 1504{
2562c823 1505 if (GetType() == wxT("arrstring") &&
cf25a599 1506 m_refData->GetRefCount() == 1)
341287bf 1507 {
2562c823 1508 ((wxVariantDataArrayString *)GetData())->SetValue(value);
341287bf
JS
1509 }
1510 else
1511 {
2562c823 1512 UnRef();
cf25a599 1513 m_refData = new wxVariantDataArrayString(value);
341287bf
JS
1514 }
1515}
1516
2562c823 1517wxArrayString wxVariant::GetArrayString() const
341287bf 1518{
2562c823
RR
1519 if ( GetType() == wxT("arrstring") )
1520 return ((wxVariantDataArrayString *)GetData())->GetValue();
1521
1522 return wxArrayString();
341287bf
JS
1523}
1524
4e00b908
JS
1525// ----------------------------------------------------------------------------
1526// wxVariantDataLongLong
1527// ----------------------------------------------------------------------------
1528
1529#if wxUSE_LONGLONG
1530
1531class WXDLLIMPEXP_BASE wxVariantDataLongLong : public wxVariantData
1532{
1533public:
1534 wxVariantDataLongLong() { m_value = 0; }
1535 wxVariantDataLongLong(wxLongLong value) { m_value = value; }
1536
1537 wxLongLong GetValue() const { return m_value; }
1538 void SetValue(wxLongLong value) { m_value = value; }
1539
1540 virtual bool Eq(wxVariantData& data) const;
1541
1542 virtual bool Read(wxString& str);
1543 virtual bool Write(wxString& str) const;
1544#if wxUSE_STD_IOSTREAM
1545 virtual bool Read(wxSTD istream& str);
1546 virtual bool Write(wxSTD ostream& str) const;
1547#endif
1548#if wxUSE_STREAMS
1549 virtual bool Read(wxInputStream& str);
1550 virtual bool Write(wxOutputStream &str) const;
1551#endif // wxUSE_STREAMS
1552
1553 wxVariantData* Clone() const
1554 {
1555 return new wxVariantDataLongLong(m_value);
1556 }
1557
1558 virtual wxString GetType() const { return wxS("longlong"); }
1559
0bf14ab8 1560 DECLARE_WXANY_CONVERSION()
4e00b908
JS
1561protected:
1562 wxLongLong m_value;
1563};
1564
0bf14ab8
JS
1565//
1566// wxLongLong type requires customized wxAny conversion code
1567//
1568#if wxUSE_ANY
1569#ifdef wxLongLong_t
1570
1571bool wxVariantDataLongLong::GetAsAny(wxAny* any) const
1572{
1573 *any = m_value.GetValue();
1574 return true;
1575}
1576
1577wxVariantData* wxVariantDataLongLong::VariantDataFactory(const wxAny& any)
1578{
1579 return new wxVariantDataLongLong(wxANY_AS(any, wxLongLong_t));
1580}
1581
1582REGISTER_WXANY_CONVERSION(wxLongLong_t, wxVariantDataLongLong)
1583
1584#else // if !defined(wxLongLong_t)
1585
1586bool wxVariantDataLongLong::GetAsAny(wxAny* any) const
1587{
1588 *any = m_value;
1589 return true;
1590}
1591
1592wxVariantData* wxVariantDataLongLong::VariantDataFactory(const wxAny& any)
1593{
1594 return new wxVariantDataLongLong(wxANY_AS(any, wxLongLong));
1595}
1596
1597REGISTER_WXANY_CONVERSION(wxLongLong, wxVariantDataLongLong)
1598
1599#endif // defined(wxLongLong_t)/!defined(wxLongLong_t)
1600#endif // wxUSE_ANY
1601
4e00b908
JS
1602bool wxVariantDataLongLong::Eq(wxVariantData& data) const
1603{
03647350 1604 wxASSERT_MSG( (data.GetType() == wxS("longlong")),
4e00b908
JS
1605 "wxVariantDataLongLong::Eq: argument mismatch" );
1606
1607 wxVariantDataLongLong& otherData = (wxVariantDataLongLong&) data;
1608
1609 return (otherData.m_value == m_value);
1610}
1611
1612#if wxUSE_STD_IOSTREAM
1613bool wxVariantDataLongLong::Write(wxSTD ostream& str) const
1614{
1615 wxString s;
1616 Write(s);
1617 str << (const char*) s.mb_str();
1618 return true;
1619}
1620#endif
1621
1622bool wxVariantDataLongLong::Write(wxString& str) const
1623{
f81bd288
JS
1624#ifdef wxLongLong_t
1625 str.Printf(wxS("%lld"), m_value.GetValue());
4e00b908 1626 return true;
f81bd288
JS
1627#else
1628 return false;
1629#endif
4e00b908
JS
1630}
1631
1632#if wxUSE_STD_IOSTREAM
1633bool wxVariantDataLongLong::Read(wxSTD istream& WXUNUSED(str))
1634{
1635 wxFAIL_MSG(wxS("Unimplemented"));
1636 return false;
1637}
1638#endif
1639
1640#if wxUSE_STREAMS
1641bool wxVariantDataLongLong::Write(wxOutputStream& str) const
1642{
1643 wxTextOutputStream s(str);
1644 s.Write32(m_value.GetLo());
1645 s.Write32(m_value.GetHi());
1646 return true;
1647}
1648
1649bool wxVariantDataLongLong::Read(wxInputStream& str)
1650{
1651 wxTextInputStream s(str);
1652 unsigned long lo = s.Read32();
1653 long hi = s.Read32();
1654 m_value = wxLongLong(hi, lo);
1655 return true;
1656}
1657#endif // wxUSE_STREAMS
1658
1659bool wxVariantDataLongLong::Read(wxString& str)
1660{
1661#ifdef wxLongLong_t
1662 wxLongLong_t value_t;
1663 if ( !str.ToLongLong(&value_t) )
1664 return false;
1665 m_value = value_t;
1666 return true;
1667#else
1668 return false;
1669#endif
1670}
1671
1672// wxVariant
1673
1674wxVariant::wxVariant(wxLongLong val, const wxString& name)
1675{
1676 m_refData = new wxVariantDataLongLong(val);
1677 m_name = name;
1678}
1679
1680bool wxVariant::operator==(wxLongLong value) const
1681{
1682 wxLongLong thisValue;
1683 if ( !Convert(&thisValue) )
1684 return false;
1685 else
1686 return (value == thisValue);
1687}
1688
1689bool wxVariant::operator!=(wxLongLong value) const
1690{
1691 return (!((*this) == value));
1692}
1693
1694void wxVariant::operator=(wxLongLong value)
1695{
1696 if ( GetType() == wxS("longlong") &&
1697 m_refData->GetRefCount() == 1 )
1698 {
1699 ((wxVariantDataLongLong*)GetData())->SetValue(value);
1700 }
1701 else
1702 {
1703 UnRef();
1704 m_refData = new wxVariantDataLongLong(value);
1705 }
1706}
1707
1708wxLongLong wxVariant::GetLongLong() const
1709{
1710 wxLongLong value;
1711 if ( Convert(&value) )
1712 {
1713 return value;
1714 }
1715 else
1716 {
1717 wxFAIL_MSG(wxT("Could not convert to a long long"));
1718 return 0;
1719 }
1720}
1721
1722#endif // wxUSE_LONGLONG
1723
1724// ----------------------------------------------------------------------------
1725// wxVariantDataULongLong
1726// ----------------------------------------------------------------------------
1727
1728#if wxUSE_LONGLONG
1729
1730class WXDLLIMPEXP_BASE wxVariantDataULongLong : public wxVariantData
1731{
1732public:
1733 wxVariantDataULongLong() { m_value = 0; }
1734 wxVariantDataULongLong(wxULongLong value) { m_value = value; }
1735
1736 wxULongLong GetValue() const { return m_value; }
1737 void SetValue(wxULongLong value) { m_value = value; }
1738
1739 virtual bool Eq(wxVariantData& data) const;
1740
1741 virtual bool Read(wxString& str);
1742 virtual bool Write(wxString& str) const;
1743#if wxUSE_STD_IOSTREAM
1744 virtual bool Read(wxSTD istream& str);
1745 virtual bool Write(wxSTD ostream& str) const;
1746#endif
1747#if wxUSE_STREAMS
1748 virtual bool Read(wxInputStream& str);
1749 virtual bool Write(wxOutputStream &str) const;
1750#endif // wxUSE_STREAMS
1751
1752 wxVariantData* Clone() const
1753 {
1754 return new wxVariantDataULongLong(m_value);
1755 }
1756
1757 virtual wxString GetType() const { return wxS("ulonglong"); }
1758
0bf14ab8 1759 DECLARE_WXANY_CONVERSION()
4e00b908
JS
1760protected:
1761 wxULongLong m_value;
1762};
1763
0bf14ab8
JS
1764//
1765// wxULongLong type requires customized wxAny conversion code
1766//
1767#if wxUSE_ANY
1768#ifdef wxLongLong_t
1769
1770bool wxVariantDataULongLong::GetAsAny(wxAny* any) const
1771{
1772 *any = m_value.GetValue();
1773 return true;
1774}
1775
1776wxVariantData* wxVariantDataULongLong::VariantDataFactory(const wxAny& any)
1777{
1778 return new wxVariantDataULongLong(wxANY_AS(any, wxULongLong_t));
1779}
1780
1781REGISTER_WXANY_CONVERSION(wxULongLong_t, wxVariantDataULongLong)
1782
1783#else // if !defined(wxLongLong_t)
1784
1785bool wxVariantDataULongLong::GetAsAny(wxAny* any) const
1786{
1787 *any = m_value;
1788 return true;
1789}
1790
1791wxVariantData* wxVariantDataULongLong::VariantDataFactory(const wxAny& any)
1792{
1793 return new wxVariantDataULongLong(wxANY_AS(any, wxULongLong));
1794}
1795
1796REGISTER_WXANY_CONVERSION(wxULongLong, wxVariantDataULongLong)
1797
1798#endif // defined(wxLongLong_t)/!defined(wxLongLong_t)
1799#endif // wxUSE_ANY
1800
1801
4e00b908
JS
1802bool wxVariantDataULongLong::Eq(wxVariantData& data) const
1803{
03647350 1804 wxASSERT_MSG( (data.GetType() == wxS("ulonglong")),
4e00b908
JS
1805 "wxVariantDataULongLong::Eq: argument mismatch" );
1806
1807 wxVariantDataULongLong& otherData = (wxVariantDataULongLong&) data;
1808
1809 return (otherData.m_value == m_value);
1810}
1811
1812#if wxUSE_STD_IOSTREAM
1813bool wxVariantDataULongLong::Write(wxSTD ostream& str) const
1814{
1815 wxString s;
1816 Write(s);
1817 str << (const char*) s.mb_str();
1818 return true;
1819}
1820#endif
1821
1822bool wxVariantDataULongLong::Write(wxString& str) const
1823{
f81bd288
JS
1824#ifdef wxLongLong_t
1825 str.Printf(wxS("%llu"), m_value.GetValue());
4e00b908 1826 return true;
f81bd288
JS
1827#else
1828 return false;
1829#endif
4e00b908
JS
1830}
1831
1832#if wxUSE_STD_IOSTREAM
1833bool wxVariantDataULongLong::Read(wxSTD istream& WXUNUSED(str))
1834{
1835 wxFAIL_MSG(wxS("Unimplemented"));
1836 return false;
1837}
1838#endif
1839
1840#if wxUSE_STREAMS
1841bool wxVariantDataULongLong::Write(wxOutputStream& str) const
1842{
1843 wxTextOutputStream s(str);
1844 s.Write32(m_value.GetLo());
1845 s.Write32(m_value.GetHi());
1846 return true;
1847}
1848
1849bool wxVariantDataULongLong::Read(wxInputStream& str)
1850{
1851 wxTextInputStream s(str);
1852 unsigned long lo = s.Read32();
1853 long hi = s.Read32();
1854 m_value = wxULongLong(hi, lo);
1855 return true;
1856}
1857#endif // wxUSE_STREAMS
1858
1859bool wxVariantDataULongLong::Read(wxString& str)
1860{
1861#ifdef wxLongLong_t
1862 wxULongLong_t value_t;
1863 if ( !str.ToULongLong(&value_t) )
1864 return false;
1865 m_value = value_t;
1866 return true;
1867#else
1868 return false;
1869#endif
1870}
1871
1872// wxVariant
1873
1874wxVariant::wxVariant(wxULongLong val, const wxString& name)
1875{
1876 m_refData = new wxVariantDataULongLong(val);
1877 m_name = name;
1878}
1879
1880bool wxVariant::operator==(wxULongLong value) const
1881{
1882 wxULongLong thisValue;
1883 if ( !Convert(&thisValue) )
1884 return false;
1885 else
1886 return (value == thisValue);
1887}
1888
1889bool wxVariant::operator!=(wxULongLong value) const
1890{
1891 return (!((*this) == value));
1892}
1893
1894void wxVariant::operator=(wxULongLong value)
1895{
1896 if ( GetType() == wxS("ulonglong") &&
1897 m_refData->GetRefCount() == 1 )
1898 {
1899 ((wxVariantDataULongLong*)GetData())->SetValue(value);
1900 }
1901 else
1902 {
1903 UnRef();
1904 m_refData = new wxVariantDataULongLong(value);
1905 }
1906}
1907
1908wxULongLong wxVariant::GetULongLong() const
1909{
1910 wxULongLong value;
1911 if ( Convert(&value) )
1912 {
1913 return value;
1914 }
1915 else
1916 {
1917 wxFAIL_MSG(wxT("Could not convert to a long long"));
1918 return 0;
1919 }
1920}
1921
1922#endif // wxUSE_LONGLONG
1923
2562c823
RR
1924// ----------------------------------------------------------------------------
1925// wxVariantDataList
1926// ----------------------------------------------------------------------------
2c3a1064 1927
2562c823 1928class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
341287bf 1929{
2562c823
RR
1930public:
1931 wxVariantDataList() {}
9a0a58f5 1932 wxVariantDataList(const wxVariantList& list);
2562c823 1933 virtual ~wxVariantDataList();
341287bf 1934
9a0a58f5
RR
1935 wxVariantList& GetValue() { return m_value; }
1936 void SetValue(const wxVariantList& value) ;
341287bf 1937
2562c823
RR
1938 virtual bool Eq(wxVariantData& data) const;
1939#if wxUSE_STD_IOSTREAM
1940 virtual bool Write(wxSTD ostream& str) const;
1941#endif
1942 virtual bool Write(wxString& str) const;
1943#if wxUSE_STD_IOSTREAM
1944 virtual bool Read(wxSTD istream& str);
1945#endif
1946 virtual bool Read(wxString& str);
47b378bd 1947 virtual wxString GetType() const { return wxT("list"); }
52e81242 1948
2562c823 1949 void Clear();
341287bf 1950
c8058a09 1951 wxVariantData* Clone() const { return new wxVariantDataList(m_value); }
0bf14ab8
JS
1952
1953 DECLARE_WXANY_CONVERSION()
2562c823 1954protected:
9a0a58f5 1955 wxVariantList m_value;
2562c823 1956};
341287bf 1957
0bf14ab8
JS
1958#if wxUSE_ANY
1959
1960//
1961// Convert to/from list of wxAnys
1962//
1963
1964WX_DEFINE_LIST(wxAnyList)
1965
1966bool wxVariantDataList::GetAsAny(wxAny* any) const
1967{
1968 wxAnyList dst;
1969 wxVariantList::compatibility_iterator node = m_value.GetFirst();
1970 while (node)
1971 {
1972 wxVariant* pVar = node->GetData();
5ceb0345 1973 dst.push_back(new wxAny(((const wxVariant&)*pVar)));
0bf14ab8
JS
1974 node = node->GetNext();
1975 }
1976
1977 *any = dst;
1978 return true;
1979}
1980
1981wxVariantData* wxVariantDataList::VariantDataFactory(const wxAny& any)
1982{
1983 wxAnyList src = wxANY_AS(any, wxAnyList);
1984 wxVariantList dst;
1985 wxAnyList::compatibility_iterator node = src.GetFirst();
1986 while (node)
1987 {
1988 wxAny* pAny = node->GetData();
1989 dst.push_back(new wxVariant(*pAny));
1990 node = node->GetNext();
1991 }
1992
1993 return new wxVariantDataList(dst);
1994}
1995
1996REGISTER_WXANY_CONVERSION(wxAnyList, wxVariantDataList)
1997
1998#endif // wxUSE_ANY
1999
9a0a58f5 2000wxVariantDataList::wxVariantDataList(const wxVariantList& list)
341287bf 2001{
2562c823 2002 SetValue(list);
341287bf
JS
2003}
2004
2562c823 2005wxVariantDataList::~wxVariantDataList()
341287bf 2006{
2562c823 2007 Clear();
341287bf
JS
2008}
2009
9a0a58f5 2010void wxVariantDataList::SetValue(const wxVariantList& value)
341287bf 2011{
2562c823 2012 Clear();
9a0a58f5 2013 wxVariantList::compatibility_iterator node = value.GetFirst();
2562c823 2014 while (node)
341287bf 2015 {
9a0a58f5 2016 wxVariant* var = node->GetData();
2562c823
RR
2017 m_value.Append(new wxVariant(*var));
2018 node = node->GetNext();
341287bf 2019 }
2562c823
RR
2020}
2021
2022void wxVariantDataList::Clear()
2023{
9a0a58f5 2024 wxVariantList::compatibility_iterator node = m_value.GetFirst();
2562c823 2025 while (node)
341287bf 2026 {
9a0a58f5 2027 wxVariant* var = node->GetData();
2562c823
RR
2028 delete var;
2029 node = node->GetNext();
341287bf 2030 }
2562c823 2031 m_value.Clear();
341287bf
JS
2032}
2033
2562c823 2034bool wxVariantDataList::Eq(wxVariantData& data) const
a0a302dc 2035{
2562c823
RR
2036 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
2037
2038 wxVariantDataList& listData = (wxVariantDataList&) data;
9a0a58f5
RR
2039 wxVariantList::compatibility_iterator node1 = m_value.GetFirst();
2040 wxVariantList::compatibility_iterator node2 = listData.GetValue().GetFirst();
2562c823
RR
2041 while (node1 && node2)
2042 {
9a0a58f5
RR
2043 wxVariant* var1 = node1->GetData();
2044 wxVariant* var2 = node2->GetData();
2562c823
RR
2045 if ((*var1) != (*var2))
2046 return false;
2047 node1 = node1->GetNext();
2048 node2 = node2->GetNext();
2049 }
2050 if (node1 || node2) return false;
2051 return true;
a0a302dc
JS
2052}
2053
2562c823
RR
2054#if wxUSE_STD_IOSTREAM
2055bool wxVariantDataList::Write(wxSTD ostream& str) const
a0a302dc 2056{
2562c823
RR
2057 wxString s;
2058 Write(s);
2059 str << (const char*) s.mb_str();
2060 return true;
a0a302dc 2061}
2562c823 2062#endif
a0a302dc 2063
2562c823 2064bool wxVariantDataList::Write(wxString& str) const
a0a302dc 2065{
2562c823 2066 str = wxEmptyString;
9a0a58f5 2067 wxVariantList::compatibility_iterator node = m_value.GetFirst();
2562c823 2068 while (node)
a0a302dc 2069 {
9a0a58f5 2070 wxVariant* var = node->GetData();
2562c823
RR
2071 if (node != m_value.GetFirst())
2072 str += wxT(" ");
2073 wxString str1;
2074 str += var->MakeString();
2075 node = node->GetNext();
a0a302dc 2076 }
2562c823
RR
2077
2078 return true;
a0a302dc 2079}
2f620946 2080
2562c823
RR
2081#if wxUSE_STD_IOSTREAM
2082bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
2f620946 2083{
2562c823
RR
2084 wxFAIL_MSG(wxT("Unimplemented"));
2085 // TODO
2086 return false;
2f620946 2087}
2562c823 2088#endif
2f620946 2089
2562c823 2090bool wxVariantDataList::Read(wxString& WXUNUSED(str))
2f620946 2091{
2562c823
RR
2092 wxFAIL_MSG(wxT("Unimplemented"));
2093 // TODO
2094 return false;
2f620946
RR
2095}
2096
2562c823
RR
2097// wxVariant
2098
9a0a58f5 2099wxVariant::wxVariant(const wxVariantList& val, const wxString& name) // List of variants
2f620946 2100{
cf25a599 2101 m_refData = new wxVariantDataList(val);
2562c823 2102 m_name = name;
2f620946 2103}
341287bf 2104
9a0a58f5 2105bool wxVariant::operator== (const wxVariantList& value) const
edca7a82 2106{
2562c823 2107 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
edca7a82 2108
2562c823
RR
2109 wxVariantDataList other(value);
2110 return (GetData()->Eq(other));
edca7a82
GT
2111}
2112
9a0a58f5 2113bool wxVariant::operator!= (const wxVariantList& value) const
edca7a82
GT
2114{
2115 return (!((*this) == value));
2116}
2117
9a0a58f5 2118void wxVariant::operator= (const wxVariantList& value)
edca7a82 2119{
2562c823 2120 if (GetType() == wxT("list") &&
cf25a599 2121 m_refData->GetRefCount() == 1)
edca7a82 2122 {
2562c823 2123 ((wxVariantDataList*)GetData())->SetValue(value);
edca7a82
GT
2124 }
2125 else
2126 {
2562c823 2127 UnRef();
cf25a599 2128 m_refData = new wxVariantDataList(value);
edca7a82
GT
2129 }
2130}
2131
9a0a58f5 2132wxVariantList& wxVariant::GetList() const
edca7a82 2133{
2562c823 2134 wxASSERT( (GetType() == wxT("list")) );
edca7a82 2135
cf25a599 2136 return (wxVariantList&) ((wxVariantDataList*) m_refData)->GetValue();
2562c823 2137}
edca7a82 2138
2562c823
RR
2139// Make empty list
2140void wxVariant::NullList()
edca7a82 2141{
2562c823 2142 SetData(new wxVariantDataList());
edca7a82
GT
2143}
2144
2562c823
RR
2145// Append to list
2146void wxVariant::Append(const wxVariant& value)
edca7a82 2147{
9a0a58f5 2148 wxVariantList& list = GetList();
2562c823
RR
2149
2150 list.Append(new wxVariant(value));
edca7a82
GT
2151}
2152
2562c823
RR
2153// Insert at front of list
2154void wxVariant::Insert(const wxVariant& value)
2155{
9a0a58f5 2156 wxVariantList& list = GetList();
fb42d7c3 2157
2562c823
RR
2158 list.Insert(new wxVariant(value));
2159}
2160
2161// Returns true if the variant is a member of the list
2162bool wxVariant::Member(const wxVariant& value) const
fb42d7c3 2163{
9a0a58f5 2164 wxVariantList& list = GetList();
fb42d7c3 2165
9a0a58f5 2166 wxVariantList::compatibility_iterator node = list.GetFirst();
2562c823
RR
2167 while (node)
2168 {
9a0a58f5 2169 wxVariant* other = node->GetData();
2562c823
RR
2170 if (value == *other)
2171 return true;
2172 node = node->GetNext();
2173 }
cab1a605 2174 return false;
fb42d7c3
VZ
2175}
2176
2562c823
RR
2177// Deletes the nth element of the list
2178bool wxVariant::Delete(size_t item)
fb42d7c3 2179{
9a0a58f5 2180 wxVariantList& list = GetList();
2562c823
RR
2181
2182 wxASSERT_MSG( (item < list.GetCount()), wxT("Invalid index to Delete") );
9a0a58f5
RR
2183 wxVariantList::compatibility_iterator node = list.Item(item);
2184 wxVariant* variant = node->GetData();
2562c823
RR
2185 delete variant;
2186 list.Erase(node);
2187 return true;
fb42d7c3
VZ
2188}
2189
2562c823
RR
2190// Clear list
2191void wxVariant::ClearList()
fb42d7c3 2192{
2562c823 2193 if (!IsNull() && (GetType() == wxT("list")))
fb42d7c3 2194 {
cf25a599 2195 ((wxVariantDataList*) m_refData)->Clear();
fb42d7c3
VZ
2196 }
2197 else
2198 {
2562c823
RR
2199 if (!GetType().IsSameAs(wxT("list")))
2200 UnRef();
fb42d7c3 2201
cf25a599 2202 m_refData = new wxVariantDataList;
2562c823 2203 }
fb42d7c3
VZ
2204}
2205
60acae80
RR
2206// Treat a list variant as an array
2207wxVariant wxVariant::operator[] (size_t idx) const
2208{
60acae80 2209 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
60acae80
RR
2210
2211 if (GetType() == wxT("list"))
2212 {
cf25a599 2213 wxVariantDataList* data = (wxVariantDataList*) m_refData;
60acae80 2214 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
9a0a58f5 2215 return *(data->GetValue().Item(idx)->GetData());
60acae80 2216 }
60acae80
RR
2217 return wxNullVariant;
2218}
2219
2220wxVariant& wxVariant::operator[] (size_t idx)
2221{
2222 // We can't return a reference to a variant for a string list, since the string
2223 // is actually stored as a char*, not a variant.
2224
2225 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
2226
cf25a599 2227 wxVariantDataList* data = (wxVariantDataList*) m_refData;
60acae80
RR
2228 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
2229
9a0a58f5 2230 return * (data->GetValue().Item(idx)->GetData());
60acae80
RR
2231}
2232
2233// Return the number of elements in a list
2234size_t wxVariant::GetCount() const
2235{
60acae80 2236 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
60acae80
RR
2237
2238 if (GetType() == wxT("list"))
2239 {
cf25a599 2240 wxVariantDataList* data = (wxVariantDataList*) m_refData;
60acae80
RR
2241 return data->GetValue().GetCount();
2242 }
60acae80
RR
2243 return 0;
2244}
2245
2562c823 2246// ----------------------------------------------------------------------------
341287bf 2247// Type conversion
2562c823
RR
2248// ----------------------------------------------------------------------------
2249
341287bf
JS
2250bool wxVariant::Convert(long* value) const
2251{
2252 wxString type(GetType());
4e00b908 2253 if (type == wxS("double"))
2562c823 2254 *value = (long) (((wxVariantDoubleData*)GetData())->GetValue());
4e00b908 2255 else if (type == wxS("long"))
341287bf 2256 *value = ((wxVariantDataLong*)GetData())->GetValue();
4e00b908 2257 else if (type == wxS("bool"))
341287bf 2258 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
4e00b908 2259 else if (type == wxS("string"))
52de37c7 2260 *value = wxAtol(((wxVariantDataString*)GetData())->GetValue());
4e00b908
JS
2261#if wxUSE_LONGLONG
2262 else if (type == wxS("longlong"))
2263 {
2264 wxLongLong v = ((wxVariantDataLongLong*)GetData())->GetValue();
2265 // Don't convert if return value would be vague
2266 if ( v < LONG_MIN || v > LONG_MAX )
2267 return false;
2268 *value = v.ToLong();
2269 }
2270 else if (type == wxS("ulonglong"))
2271 {
2272 wxULongLong v = ((wxVariantDataULongLong*)GetData())->GetValue();
2273 // Don't convert if return value would be vague
2274 if ( v.GetHi() )
2275 return false;
2276 *value = (long) v.ToULong();
2277 }
2278#endif
341287bf 2279 else
cab1a605 2280 return false;
341287bf 2281
cab1a605 2282 return true;
341287bf
JS
2283}
2284
2285bool wxVariant::Convert(bool* value) const
2286{
2287 wxString type(GetType());
223d09f6 2288 if (type == wxT("double"))
2562c823 2289 *value = ((int) (((wxVariantDoubleData*)GetData())->GetValue()) != 0);
223d09f6 2290 else if (type == wxT("long"))
341287bf 2291 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
223d09f6 2292 else if (type == wxT("bool"))
341287bf 2293 *value = ((wxVariantDataBool*)GetData())->GetValue();
223d09f6 2294 else if (type == wxT("string"))
341287bf
JS
2295 {
2296 wxString val(((wxVariantDataString*)GetData())->GetValue());
2297 val.MakeLower();
b1638abf 2298 if (val == wxT("true") || val == wxT("yes") || val == wxT('1') )
cab1a605 2299 *value = true;
b1638abf 2300 else if (val == wxT("false") || val == wxT("no") || val == wxT('0') )
cab1a605 2301 *value = false;
341287bf 2302 else
cab1a605 2303 return false;
341287bf
JS
2304 }
2305 else
cab1a605 2306 return false;
341287bf 2307
cab1a605 2308 return true;
341287bf
JS
2309}
2310
2311bool wxVariant::Convert(double* value) const
2312{
2313 wxString type(GetType());
223d09f6 2314 if (type == wxT("double"))
2562c823 2315 *value = ((wxVariantDoubleData*)GetData())->GetValue();
223d09f6 2316 else if (type == wxT("long"))
341287bf 2317 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
223d09f6 2318 else if (type == wxT("bool"))
341287bf 2319 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
223d09f6 2320 else if (type == wxT("string"))
52de37c7 2321 *value = (double) wxAtof(((wxVariantDataString*)GetData())->GetValue());
4e00b908
JS
2322#if wxUSE_LONGLONG
2323 else if (type == wxS("longlong"))
2324 {
2325 *value = ((wxVariantDataLongLong*)GetData())->GetValue().ToDouble();
2326 }
2327 else if (type == wxS("ulonglong"))
2328 {
2329 *value = ((wxVariantDataULongLong*)GetData())->GetValue().ToDouble();
2330 }
2331#endif
341287bf 2332 else
cab1a605 2333 return false;
341287bf 2334
cab1a605 2335 return true;
341287bf
JS
2336}
2337
af717fa8 2338bool wxVariant::Convert(wxUniChar* value) const
341287bf
JS
2339{
2340 wxString type(GetType());
223d09f6 2341 if (type == wxT("char"))
341287bf 2342 *value = ((wxVariantDataChar*)GetData())->GetValue();
223d09f6 2343 else if (type == wxT("long"))
341287bf 2344 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
223d09f6 2345 else if (type == wxT("bool"))
341287bf
JS
2346 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
2347 else
cab1a605 2348 return false;
341287bf 2349
cab1a605 2350 return true;
341287bf
JS
2351}
2352
af717fa8
VS
2353bool wxVariant::Convert(char* value) const
2354{
2355 wxUniChar ch;
2356 if ( !Convert(&ch) )
2357 return false;
2358 *value = ch;
2359 return true;
2360}
2361
2362bool wxVariant::Convert(wchar_t* value) const
2363{
2364 wxUniChar ch;
2365 if ( !Convert(&ch) )
2366 return false;
2367 *value = ch;
2368 return true;
2369}
2370
341287bf
JS
2371bool wxVariant::Convert(wxString* value) const
2372{
2373 *value = MakeString();
cab1a605 2374 return true;
341287bf
JS
2375}
2376
4e00b908
JS
2377#if wxUSE_LONGLONG
2378bool wxVariant::Convert(wxLongLong* value) const
2379{
2380 wxString type(GetType());
2381 if (type == wxS("longlong"))
2382 *value = ((wxVariantDataLongLong*)GetData())->GetValue();
2383 else if (type == wxS("long"))
2384 *value = ((wxVariantDataLong*)GetData())->GetValue();
2385 else if (type == wxS("string"))
2386 {
2387 wxString s = ((wxVariantDataString*)GetData())->GetValue();
2388#ifdef wxLongLong_t
2389 wxLongLong_t value_t;
2390 if ( !s.ToLongLong(&value_t) )
2391 return false;
2392 *value = value_t;
2393#else
2394 long l_value;
2395 if ( !s.ToLong(&l_value) )
2396 return false;
2397 *value = l_value;
2398#endif
2399 }
2400 else if (type == wxS("bool"))
2401 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
2402 else if (type == wxS("double"))
2403 {
2404 value->Assign(((wxVariantDoubleData*)GetData())->GetValue());
2405 }
2406 else if (type == wxS("ulonglong"))
2407 *value = ((wxVariantDataULongLong*)GetData())->GetValue();
2408 else
2409 return false;
2410
2411 return true;
2412}
2413
2414bool wxVariant::Convert(wxULongLong* value) const
2415{
2416 wxString type(GetType());
2417 if (type == wxS("ulonglong"))
2418 *value = ((wxVariantDataULongLong*)GetData())->GetValue();
2419 else if (type == wxS("long"))
2420 *value = ((wxVariantDataLong*)GetData())->GetValue();
2421 else if (type == wxS("string"))
2422 {
2423 wxString s = ((wxVariantDataString*)GetData())->GetValue();
2424#ifdef wxLongLong_t
2425 wxULongLong_t value_t;
2426 if ( !s.ToULongLong(&value_t) )
2427 return false;
2428 *value = value_t;
2429#else
2430 unsigned long l_value;
2431 if ( !s.ToULong(&l_value) )
2432 return false;
2433 *value = l_value;
2434#endif
2435 }
2436 else if (type == wxS("bool"))
2437 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
2438 else if (type == wxS("double"))
2439 {
2440 double value_d = ((wxVariantDoubleData*)GetData())->GetValue();
2441
2442 if ( value_d < 0.0 )
2443 return false;
2444
2445#ifdef wxLongLong_t
2446 *value = (wxULongLong_t) value_d;
2447#else
2448 wxLongLong temp;
2449 temp.Assign(value_d);
2450 *value = temp;
2451#endif
2452 }
2453 else if (type == wxS("longlong"))
2454 *value = ((wxVariantDataLongLong*)GetData())->GetValue();
2455 else
2456 return false;
2457
2458 return true;
2459}
2460#endif // wxUSE_LONGLONG
2461
e2b87f38 2462#if wxUSE_DATETIME
edca7a82
GT
2463bool wxVariant::Convert(wxDateTime* value) const
2464{
2465 wxString type(GetType());
2466 if (type == wxT("datetime"))
9708db20 2467 {
edca7a82 2468 *value = ((wxVariantDataDateTime*)GetData())->GetValue();
cab1a605 2469 return true;
dc259b79 2470 }
73799292 2471
9708db20
JS
2472 // Fallback to string conversion
2473 wxString val;
73799292
VZ
2474 if ( !Convert(&val) )
2475 return false;
2476
2477 // Try to parse this as either date and time, only date or only time
2478 // checking that the entire string was parsed
2479 wxString::const_iterator end;
2480 if ( value->ParseDateTime(val, &end) && end == val.end() )
2481 return true;
2482
2483 if ( value->ParseDate(val, &end) && end == val.end() )
2484 return true;
2485
2486 if ( value->ParseTime(val, &end) && end == val.end() )
2487 return true;
2488
2489 return false;
edca7a82 2490}
b1e343f2 2491#endif // wxUSE_DATETIME
d5dc103f
VZ
2492
2493#endif // wxUSE_VARIANT