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