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