]> git.saurik.com Git - wxWidgets.git/blame - src/common/variant.cpp
fixed crash when setting locale
[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
341287bf
JS
52IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject)
53
fd242375 54wxVariant WXDLLIMPEXP_BASE wxNullVariant;
341287bf 55
2562c823 56
341287bf 57/*
2562c823 58 * wxVariant
341287bf
JS
59 */
60
2562c823 61IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
341287bf 62
2562c823 63wxVariant::wxVariant()
341287bf 64{
2562c823 65 m_data = (wxVariantData*) NULL;
341287bf
JS
66}
67
2562c823 68bool wxVariant::IsNull() const
341287bf 69{
2562c823 70 return (m_data == (wxVariantData*) NULL);
341287bf
JS
71}
72
2562c823 73void wxVariant::MakeNull()
341287bf 74{
2562c823 75 UnRef();
341287bf
JS
76}
77
2562c823 78void wxVariant::Clear()
341287bf 79{
2562c823 80 m_name = wxEmptyString;
341287bf
JS
81}
82
2562c823
RR
83wxVariant::wxVariant(const wxVariant& variant)
84 : wxObject()
341287bf 85{
2562c823 86 m_data = (wxVariantData*) NULL;
341287bf 87
2562c823
RR
88 if (!variant.IsNull())
89 Ref(variant);
341287bf 90
2562c823 91 m_name = variant.m_name;
341287bf
JS
92}
93
2562c823 94wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
341287bf 95{
2562c823
RR
96 m_data = data;
97 m_name = name;
341287bf
JS
98}
99
2562c823 100wxVariant::~wxVariant()
341287bf 101{
2562c823 102 UnRef();
341287bf
JS
103}
104
2562c823
RR
105// Assignment
106void wxVariant::operator= (const wxVariant& variant)
341287bf 107{
2562c823
RR
108 Ref(variant);
109 m_name = variant.m_name;
341287bf
JS
110}
111
2562c823
RR
112// myVariant = new wxStringVariantData("hello")
113void wxVariant::operator= (wxVariantData* variantData)
341287bf 114{
2562c823
RR
115 UnRef();
116 m_data = variantData;
341287bf
JS
117}
118
2562c823 119bool wxVariant::operator== (const wxVariant& variant) const
341287bf 120{
2562c823
RR
121 if (IsNull() || variant.IsNull())
122 return (IsNull() == variant.IsNull());
341287bf 123
2562c823
RR
124 return (GetData()->Eq(* variant.GetData()));
125}
341287bf 126
2562c823 127bool wxVariant::operator!= (const wxVariant& variant) const
341287bf 128{
2562c823
RR
129 return (!(*this == variant));
130}
341287bf 131
341287bf 132
2562c823 133wxString wxVariant::MakeString() const
341287bf 134{
2562c823
RR
135 if (!IsNull())
136 {
137 wxString str;
138 if (GetData()->Write(str))
139 return str;
140 }
141 return wxEmptyString;
341287bf
JS
142}
143
2562c823 144void wxVariant::SetData(wxVariantData* data)
341287bf 145{
2562c823
RR
146 UnRef();
147 m_data = data;
341287bf
JS
148}
149
2562c823 150void wxVariant::Ref(const wxVariant& clone)
341287bf 151{
2562c823
RR
152 // nothing to be done
153 if (m_data == clone.m_data)
154 return;
341287bf 155
2562c823
RR
156 // delete reference to old data
157 UnRef();
158
159 // reference new data
160 if ( clone.m_data )
341287bf 161 {
2562c823
RR
162 m_data = clone.m_data;
163 m_data->m_count++;
341287bf 164 }
341287bf
JS
165}
166
341287bf 167
2562c823 168void wxVariant::UnRef()
341287bf 169{
2562c823 170 if ( m_data )
341287bf 171 {
2562c823
RR
172 wxASSERT_MSG( m_data->m_count > 0, _T("invalid ref data count") );
173
174 m_data->DecRef();
175 m_data = NULL;
341287bf 176 }
2562c823 177}
341287bf 178
2562c823
RR
179
180// Returns a string representing the type of the variant,
181// e.g. "string", "bool", "list", "double", "long"
182wxString wxVariant::GetType() const
183{
184 if (IsNull())
185 return wxString(wxT("null"));
186 else
187 return GetData()->GetType();
341287bf
JS
188}
189
2562c823
RR
190
191bool wxVariant::IsType(const wxString& type) const
341287bf 192{
2562c823 193 return (GetType() == type);
341287bf
JS
194}
195
2562c823 196bool wxVariant::IsValueKindOf(const wxClassInfo* type) const
341287bf 197{
2562c823
RR
198 wxClassInfo* info=GetData()->GetValueClassInfo();
199 return info ? info->IsKindOf(type) : false ;
341287bf
JS
200}
201
2c3a1064 202
2562c823
RR
203// -----------------------------------------------------------------
204// wxVariantDataLong
205// -----------------------------------------------------------------
341287bf 206
fd242375 207class WXDLLIMPEXP_BASE wxVariantDataLong: public wxVariantData
341287bf
JS
208{
209DECLARE_DYNAMIC_CLASS(wxVariantDataLong)
210public:
211 wxVariantDataLong() { m_value = 0; }
212 wxVariantDataLong(long value) { m_value = value; }
213
214 inline long GetValue() const { return m_value; }
215 inline void SetValue(long value) { m_value = value; }
216
341287bf 217 virtual bool Eq(wxVariantData& data) const;
1ccbb61a
VZ
218
219 virtual bool Read(wxString& str);
341287bf 220 virtual bool Write(wxString& str) const;
38830220 221#if wxUSE_STD_IOSTREAM
dd107c50
VZ
222 virtual bool Read(wxSTD istream& str);
223 virtual bool Write(wxSTD ostream& str) const;
38830220 224#endif
e02afc7a 225#if wxUSE_STREAMS
75ed1d15 226 virtual bool Read(wxInputStream& str);
1ccbb61a 227 virtual bool Write(wxOutputStream &str) const;
e02afc7a 228#endif // wxUSE_STREAMS
1ccbb61a 229
47b378bd 230 virtual wxString GetType() const { return wxT("long"); }
341287bf
JS
231
232protected:
233 long m_value;
234};
235
236IMPLEMENT_DYNAMIC_CLASS(wxVariantDataLong, wxVariantData)
237
341287bf
JS
238bool wxVariantDataLong::Eq(wxVariantData& data) const
239{
223d09f6 240 wxASSERT_MSG( (data.GetType() == wxT("long")), wxT("wxVariantDataLong::Eq: argument mismatch") );
341287bf
JS
241
242 wxVariantDataLong& otherData = (wxVariantDataLong&) data;
243
244 return (otherData.m_value == m_value);
245}
246
38830220 247#if wxUSE_STD_IOSTREAM
dd107c50 248bool wxVariantDataLong::Write(wxSTD ostream& str) const
341287bf
JS
249{
250 wxString s;
251 Write(s);
783b6cfd 252 str << (const char*) s.mb_str();
cab1a605 253 return true;
341287bf 254}
38830220 255#endif
341287bf
JS
256
257bool wxVariantDataLong::Write(wxString& str) const
258{
223d09f6 259 str.Printf(wxT("%ld"), m_value);
cab1a605 260 return true;
341287bf
JS
261}
262
38830220 263#if wxUSE_STD_IOSTREAM
dd107c50 264bool wxVariantDataLong::Read(wxSTD istream& str)
341287bf
JS
265{
266 str >> m_value;
cab1a605 267 return true;
341287bf 268}
38830220 269#endif
341287bf 270
e02afc7a 271#if wxUSE_STREAMS
1ccbb61a
VZ
272bool wxVariantDataLong::Write(wxOutputStream& str) const
273{
fae05df5
GL
274 wxTextOutputStream s(str);
275
479cd5de 276 s.Write32((size_t)m_value);
cab1a605 277 return true;
1ccbb61a
VZ
278}
279
75ed1d15
GL
280bool wxVariantDataLong::Read(wxInputStream& str)
281{
fae05df5
GL
282 wxTextInputStream s(str);
283 m_value = s.Read32();
cab1a605 284 return true;
75ed1d15 285}
e02afc7a 286#endif // wxUSE_STREAMS
75ed1d15 287
341287bf
JS
288bool wxVariantDataLong::Read(wxString& str)
289{
52de37c7 290 m_value = wxAtol(str);
cab1a605 291 return true;
341287bf
JS
292}
293
07502d73 294// wxVariant
341287bf 295
2562c823 296wxVariant::wxVariant(long val, const wxString& name)
341287bf 297{
2562c823
RR
298 m_data = new wxVariantDataLong(val);
299 m_name = name;
300}
341287bf 301
2562c823
RR
302wxVariant::wxVariant(int val, const wxString& name)
303{
304 m_data = new wxVariantDataLong((long)val);
305 m_name = name;
306}
307
308wxVariant::wxVariant(short val, const wxString& name)
309{
310 m_data = new wxVariantDataLong((long)val);
311 m_name = name;
312}
313
314bool wxVariant::operator== (long value) const
315{
316 long thisValue;
317 if (!Convert(&thisValue))
318 return false;
319 else
320 return (value == thisValue);
321}
322
323bool wxVariant::operator!= (long value) const
324{
325 return (!((*this) == value));
326}
327
328void wxVariant::operator= (long value)
329{
330 if (GetType() == wxT("long") &&
331 m_data->GetRefCount() == 1)
332 {
333 ((wxVariantDataLong*)GetData())->SetValue(value);
334 }
335 else
336 {
337 UnRef();
338 m_data = new wxVariantDataLong(value);
339 }
340}
341
342long wxVariant::GetLong() const
343{
344 long value;
345 if (Convert(& value))
346 return value;
347 else
348 {
349 wxFAIL_MSG(wxT("Could not convert to a long"));
350 return 0;
351 }
352}
353
354// -----------------------------------------------------------------
355// wxVariantDoubleData
356// -----------------------------------------------------------------
357
358class WXDLLIMPEXP_BASE wxVariantDoubleData: public wxVariantData
359{
360DECLARE_DYNAMIC_CLASS(wxVariantDoubleData)
361public:
362 wxVariantDoubleData() { m_value = 0.0; }
363 wxVariantDoubleData(double value) { m_value = value; }
364
365 inline double GetValue() const { return m_value; }
366 inline void SetValue(double value) { m_value = value; }
341287bf 367
341287bf 368 virtual bool Eq(wxVariantData& data) const;
1ccbb61a 369 virtual bool Read(wxString& str);
38830220 370#if wxUSE_STD_IOSTREAM
dd107c50 371 virtual bool Write(wxSTD ostream& str) const;
38830220 372#endif
341287bf 373 virtual bool Write(wxString& str) const;
38830220 374#if wxUSE_STD_IOSTREAM
dd107c50 375 virtual bool Read(wxSTD istream& str);
38830220 376#endif
e02afc7a 377#if wxUSE_STREAMS
75ed1d15 378 virtual bool Read(wxInputStream& str);
1ccbb61a 379 virtual bool Write(wxOutputStream &str) const;
e02afc7a 380#endif // wxUSE_STREAMS
47b378bd 381 virtual wxString GetType() const { return wxT("double"); }
341287bf
JS
382
383protected:
384 double m_value;
385};
386
2562c823 387IMPLEMENT_DYNAMIC_CLASS(wxVariantDoubleData, wxVariantData)
341287bf 388
2562c823 389bool wxVariantDoubleData::Eq(wxVariantData& data) const
341287bf 390{
2562c823 391 wxASSERT_MSG( (data.GetType() == wxT("double")), wxT("wxVariantDoubleData::Eq: argument mismatch") );
341287bf 392
2562c823 393 wxVariantDoubleData& otherData = (wxVariantDoubleData&) data;
341287bf 394
bc14c8b2 395 return wxIsSameDouble(otherData.m_value, m_value);
341287bf
JS
396}
397
38830220 398#if wxUSE_STD_IOSTREAM
2562c823 399bool wxVariantDoubleData::Write(wxSTD ostream& str) const
341287bf
JS
400{
401 wxString s;
402 Write(s);
783b6cfd 403 str << (const char*) s.mb_str();
cab1a605 404 return true;
341287bf 405}
38830220 406#endif
341287bf 407
2562c823 408bool wxVariantDoubleData::Write(wxString& str) const
341287bf 409{
654056ee 410 str.Printf(wxT("%.14g"), m_value);
cab1a605 411 return true;
341287bf
JS
412}
413
38830220 414#if wxUSE_STD_IOSTREAM
2562c823 415bool wxVariantDoubleData::Read(wxSTD istream& str)
341287bf
JS
416{
417 str >> m_value;
cab1a605 418 return true;
341287bf 419}
38830220 420#endif
341287bf 421
e02afc7a 422#if wxUSE_STREAMS
2562c823 423bool wxVariantDoubleData::Write(wxOutputStream& str) const
1ccbb61a 424{
fae05df5
GL
425 wxTextOutputStream s(str);
426 s.WriteDouble((double)m_value);
cab1a605 427 return true;
1ccbb61a
VZ
428}
429
2562c823 430bool wxVariantDoubleData::Read(wxInputStream& str)
75ed1d15 431{
fae05df5
GL
432 wxTextInputStream s(str);
433 m_value = (float)s.ReadDouble();
cab1a605 434 return true;
75ed1d15 435}
e02afc7a 436#endif // wxUSE_STREAMS
75ed1d15 437
2562c823 438bool wxVariantDoubleData::Read(wxString& str)
341287bf 439{
52de37c7 440 m_value = wxAtof(str);
cab1a605 441 return true;
341287bf
JS
442}
443
2562c823
RR
444// wxVariant double code
445
446wxVariant::wxVariant(double val, const wxString& name)
447{
448 m_data = new wxVariantDoubleData(val);
449 m_name = name;
450}
451
452bool wxVariant::operator== (double value) const
453{
454 double thisValue;
455 if (!Convert(&thisValue))
456 return false;
457
458 return wxIsSameDouble(value, thisValue);
459}
460
461bool wxVariant::operator!= (double value) const
462{
463 return (!((*this) == value));
464}
465
466void wxVariant::operator= (double value)
467{
468 if (GetType() == wxT("double") &&
469 m_data->GetRefCount() == 1)
470 {
471 ((wxVariantDoubleData*)GetData())->SetValue(value);
472 }
473 else
474 {
475 UnRef();
476 m_data = new wxVariantDoubleData(value);
477 }
478}
479
480double wxVariant::GetDouble() const
481{
482 double value;
483 if (Convert(& value))
484 return value;
485 else
486 {
487 wxFAIL_MSG(wxT("Could not convert to a double number"));
488 return 0.0;
489 }
490}
491
492// -----------------------------------------------------------------
493// wxVariantBoolData
494// -----------------------------------------------------------------
495
57493f9f 496#ifdef HAVE_BOOL
341287bf 497
fd242375 498class WXDLLIMPEXP_BASE wxVariantDataBool: public wxVariantData
341287bf
JS
499{
500DECLARE_DYNAMIC_CLASS(wxVariantDataBool)
501public:
502 wxVariantDataBool() { m_value = 0; }
503 wxVariantDataBool(bool value) { m_value = value; }
504
505 inline bool GetValue() const { return m_value; }
506 inline void SetValue(bool value) { m_value = value; }
507
341287bf 508 virtual bool Eq(wxVariantData& data) const;
38830220 509#if wxUSE_STD_IOSTREAM
dd107c50 510 virtual bool Write(wxSTD ostream& str) const;
38830220 511#endif
341287bf 512 virtual bool Write(wxString& str) const;
1ccbb61a 513 virtual bool Read(wxString& str);
38830220 514#if wxUSE_STD_IOSTREAM
dd107c50 515 virtual bool Read(wxSTD istream& str);
38830220 516#endif
e02afc7a 517#if wxUSE_STREAMS
75ed1d15 518 virtual bool Read(wxInputStream& str);
1ccbb61a 519 virtual bool Write(wxOutputStream& str) const;
e02afc7a 520#endif // wxUSE_STREAMS
47b378bd 521 virtual wxString GetType() const { return wxT("bool"); }
341287bf
JS
522
523protected:
524 bool m_value;
525};
526
527IMPLEMENT_DYNAMIC_CLASS(wxVariantDataBool, wxVariantData)
528
341287bf
JS
529bool wxVariantDataBool::Eq(wxVariantData& data) const
530{
223d09f6 531 wxASSERT_MSG( (data.GetType() == wxT("bool")), wxT("wxVariantDataBool::Eq: argument mismatch") );
341287bf
JS
532
533 wxVariantDataBool& otherData = (wxVariantDataBool&) data;
534
535 return (otherData.m_value == m_value);
536}
537
38830220 538#if wxUSE_STD_IOSTREAM
dd107c50 539bool wxVariantDataBool::Write(wxSTD ostream& str) const
341287bf
JS
540{
541 wxString s;
542 Write(s);
783b6cfd 543 str << (const char*) s.mb_str();
cab1a605 544 return true;
341287bf 545}
38830220 546#endif
341287bf
JS
547
548bool wxVariantDataBool::Write(wxString& str) const
549{
223d09f6 550 str.Printf(wxT("%d"), (int) m_value);
cab1a605 551 return true;
341287bf
JS
552}
553
38830220 554#if wxUSE_STD_IOSTREAM
dd107c50 555bool wxVariantDataBool::Read(wxSTD istream& WXUNUSED(str))
341287bf 556{
223d09f6 557 wxFAIL_MSG(wxT("Unimplemented"));
341287bf 558// str >> (long) m_value;
cab1a605 559 return false;
341287bf 560}
38830220 561#endif
341287bf 562
e02afc7a 563#if wxUSE_STREAMS
1ccbb61a
VZ
564bool wxVariantDataBool::Write(wxOutputStream& str) const
565{
fae05df5
GL
566 wxTextOutputStream s(str);
567
2b004197 568 s.Write8(m_value);
cab1a605 569 return true;
1ccbb61a
VZ
570}
571
75ed1d15
GL
572bool wxVariantDataBool::Read(wxInputStream& str)
573{
fae05df5
GL
574 wxTextInputStream s(str);
575
a1b82138 576 m_value = s.Read8() != 0;
cab1a605 577 return true;
75ed1d15 578}
e02afc7a 579#endif // wxUSE_STREAMS
75ed1d15 580
341287bf
JS
581bool wxVariantDataBool::Read(wxString& str)
582{
52de37c7 583 m_value = (wxAtol(str) != 0);
cab1a605 584 return true;
341287bf 585}
2562c823
RR
586
587// wxVariant ****
588
589wxVariant::wxVariant(bool val, const wxString& name)
590{
591 m_data = new wxVariantDataBool(val);
592 m_name = name;
593}
594
595bool wxVariant::operator== (bool value) const
596{
597 bool thisValue;
598 if (!Convert(&thisValue))
599 return false;
600 else
601 return (value == thisValue);
602}
603
604bool wxVariant::operator!= (bool value) const
605{
606 return (!((*this) == value));
607}
608
609void wxVariant::operator= (bool value)
610{
611 if (GetType() == wxT("bool") &&
612 m_data->GetRefCount() == 1)
613 {
614 ((wxVariantDataBool*)GetData())->SetValue(value);
615 }
616 else
617 {
618 UnRef();
619 m_data = new wxVariantDataBool(value);
620 }
621}
622
623bool wxVariant::GetBool() const
624{
625 bool value;
626 if (Convert(& value))
627 return value;
628 else
629 {
630 wxFAIL_MSG(wxT("Could not convert to a bool"));
631 return 0;
632 }
633}
634
57493f9f 635#endif // HAVE_BOOL
341287bf 636
2562c823
RR
637// -----------------------------------------------------------------
638// wxVariantDataChar
639// -----------------------------------------------------------------
341287bf 640
fd242375 641class WXDLLIMPEXP_BASE wxVariantDataChar: public wxVariantData
341287bf
JS
642{
643DECLARE_DYNAMIC_CLASS(wxVariantDataChar)
644public:
645 wxVariantDataChar() { m_value = 0; }
71520754 646 wxVariantDataChar(wxChar value) { m_value = value; }
341287bf 647
71520754
RR
648 inline wxChar GetValue() const { return m_value; }
649 inline void SetValue(wxChar value) { m_value = value; }
341287bf 650
341287bf 651 virtual bool Eq(wxVariantData& data) const;
38830220 652#if wxUSE_STD_IOSTREAM
dd107c50
VZ
653 virtual bool Read(wxSTD istream& str);
654 virtual bool Write(wxSTD ostream& str) const;
38830220 655#endif
1ccbb61a 656 virtual bool Read(wxString& str);
341287bf 657 virtual bool Write(wxString& str) const;
e02afc7a 658#if wxUSE_STREAMS
75ed1d15 659 virtual bool Read(wxInputStream& str);
1ccbb61a 660 virtual bool Write(wxOutputStream& str) const;
e02afc7a 661#endif // wxUSE_STREAMS
47b378bd 662 virtual wxString GetType() const { return wxT("char"); }
341287bf
JS
663
664protected:
71520754 665 wxChar m_value;
341287bf
JS
666};
667
668IMPLEMENT_DYNAMIC_CLASS(wxVariantDataChar, wxVariantData)
669
341287bf
JS
670bool wxVariantDataChar::Eq(wxVariantData& data) const
671{
223d09f6 672 wxASSERT_MSG( (data.GetType() == wxT("char")), wxT("wxVariantDataChar::Eq: argument mismatch") );
341287bf
JS
673
674 wxVariantDataChar& otherData = (wxVariantDataChar&) data;
675
676 return (otherData.m_value == m_value);
677}
678
38830220 679#if wxUSE_STD_IOSTREAM
dd107c50 680bool wxVariantDataChar::Write(wxSTD ostream& str) const
341287bf
JS
681{
682 wxString s;
683 Write(s);
783b6cfd 684 str << (const char*) s.mb_str();
cab1a605 685 return true;
341287bf 686}
38830220 687#endif
341287bf
JS
688
689bool wxVariantDataChar::Write(wxString& str) const
690{
223d09f6 691 str.Printf(wxT("%c"), m_value);
cab1a605 692 return true;
341287bf
JS
693}
694
38830220 695#if wxUSE_STD_IOSTREAM
dd107c50 696bool wxVariantDataChar::Read(wxSTD istream& WXUNUSED(str))
341287bf 697{
223d09f6 698 wxFAIL_MSG(wxT("Unimplemented"));
07502d73 699
cab1a605 700 return false;
341287bf 701}
38830220 702#endif
341287bf 703
e02afc7a 704#if wxUSE_STREAMS
1ccbb61a
VZ
705bool wxVariantDataChar::Write(wxOutputStream& str) const
706{
fae05df5
GL
707 wxTextOutputStream s(str);
708
07502d73
WS
709 s << m_value;
710
cab1a605 711 return true;
1ccbb61a
VZ
712}
713
75ed1d15
GL
714bool wxVariantDataChar::Read(wxInputStream& str)
715{
fae05df5
GL
716 wxTextInputStream s(str);
717
71520754
RR
718 s >> m_value;
719
cab1a605 720 return true;
75ed1d15 721}
e02afc7a 722#endif // wxUSE_STREAMS
75ed1d15 723
341287bf
JS
724bool wxVariantDataChar::Read(wxString& str)
725{
71520754 726 m_value = str[size_t(0)];
cab1a605 727 return true;
341287bf
JS
728}
729
71520754 730wxVariant::wxVariant(wxChar val, const wxString& name)
2562c823
RR
731{
732 m_data = new wxVariantDataChar(val);
733 m_name = name;
734}
735
71520754 736bool wxVariant::operator== (wxChar value) const
2562c823 737{
38f82bf6 738 wxChar thisValue;
2562c823
RR
739 if (!Convert(&thisValue))
740 return false;
741 else
742 return (value == thisValue);
743}
744
71520754 745bool wxVariant::operator!= (wxChar value) const
2562c823
RR
746{
747 return (!((*this) == value));
748}
749
71520754 750void wxVariant::operator= (wxChar value)
2562c823
RR
751{
752 if (GetType() == wxT("char") &&
753 m_data->GetRefCount() == 1)
754 {
755 ((wxVariantDataChar*)GetData())->SetValue(value);
756 }
757 else
758 {
759 UnRef();
760 m_data = new wxVariantDataChar(value);
761 }
762}
763
71520754 764wxChar wxVariant::GetChar() const
2562c823 765{
38f82bf6 766 wxChar value;
2562c823
RR
767 if (Convert(& value))
768 return value;
769 else
770 {
771 wxFAIL_MSG(wxT("Could not convert to a char"));
772 return 0;
773 }
774}
775
776// ----------------------------------------------------------------------------
777// wxVariantDataString
778// ----------------------------------------------------------------------------
341287bf 779
fd242375 780class WXDLLIMPEXP_BASE wxVariantDataString: public wxVariantData
341287bf
JS
781{
782DECLARE_DYNAMIC_CLASS(wxVariantDataString)
783public:
784 wxVariantDataString() { }
785 wxVariantDataString(const wxString& value) { m_value = value; }
786
787 inline wxString GetValue() const { return m_value; }
788 inline void SetValue(const wxString& value) { m_value = value; }
789
341287bf 790 virtual bool Eq(wxVariantData& data) const;
38830220 791#if wxUSE_STD_IOSTREAM
dd107c50 792 virtual bool Write(wxSTD ostream& str) const;
38830220 793#endif
1ccbb61a 794 virtual bool Read(wxString& str);
341287bf 795 virtual bool Write(wxString& str) const;
38830220 796#if wxUSE_STD_IOSTREAM
47b378bd 797 virtual bool Read(wxSTD istream& WXUNUSED(str)) { return false; }
38830220 798#endif
e02afc7a 799#if wxUSE_STREAMS
75ed1d15 800 virtual bool Read(wxInputStream& str);
1ccbb61a 801 virtual bool Write(wxOutputStream& str) const;
e02afc7a 802#endif // wxUSE_STREAMS
47b378bd 803 virtual wxString GetType() const { return wxT("string"); }
341287bf
JS
804
805protected:
806 wxString m_value;
807};
808
341287bf
JS
809bool wxVariantDataString::Eq(wxVariantData& data) const
810{
223d09f6 811 wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
341287bf
JS
812
813 wxVariantDataString& otherData = (wxVariantDataString&) data;
814
815 return (otherData.m_value == m_value);
816}
817
38830220 818#if wxUSE_STD_IOSTREAM
dd107c50 819bool wxVariantDataString::Write(wxSTD ostream& str) const
341287bf 820{
783b6cfd 821 str << (const char*) m_value.mb_str();
cab1a605 822 return true;
341287bf 823}
38830220 824#endif
341287bf
JS
825
826bool wxVariantDataString::Write(wxString& str) const
827{
828 str = m_value;
cab1a605 829 return true;
341287bf
JS
830}
831
e02afc7a 832#if wxUSE_STREAMS
1ccbb61a
VZ
833bool wxVariantDataString::Write(wxOutputStream& str) const
834{
783b6cfd 835 // why doesn't wxOutputStream::operator<< take "const wxString&"
fae05df5
GL
836 wxTextOutputStream s(str);
837 s.WriteString(m_value);
cab1a605 838 return true;
1ccbb61a
VZ
839}
840
75ed1d15
GL
841bool wxVariantDataString::Read(wxInputStream& str)
842{
fae05df5
GL
843 wxTextInputStream s(str);
844
40ff126a 845 m_value = s.ReadLine();
cab1a605 846 return true;
75ed1d15 847}
e02afc7a 848#endif // wxUSE_STREAMS
75ed1d15 849
341287bf
JS
850bool wxVariantDataString::Read(wxString& str)
851{
852 m_value = str;
cab1a605 853 return true;
341287bf
JS
854}
855
856IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
857
2562c823 858// wxVariant ****
07502d73 859
2562c823 860wxVariant::wxVariant(const wxString& val, const wxString& name)
a0a302dc 861{
2562c823
RR
862 m_data = new wxVariantDataString(val);
863 m_name = name;
864}
a0a302dc 865
2562c823 866wxVariant::wxVariant(const wxChar* val, const wxString& name)
a0a302dc 867{
2562c823
RR
868 m_data = new wxVariantDataString(wxString(val));
869 m_name = name;
870}
a0a302dc 871
2562c823
RR
872bool wxVariant::operator== (const wxString& value) const
873{
874 wxString thisValue;
875 if (!Convert(&thisValue))
876 return false;
a0a302dc 877
2562c823 878 return value == thisValue;
a0a302dc
JS
879}
880
2562c823 881bool wxVariant::operator!= (const wxString& value) const
a0a302dc 882{
2562c823 883 return (!((*this) == value));
a0a302dc
JS
884}
885
2562c823 886void wxVariant::operator= (const wxString& value)
a0a302dc 887{
2562c823
RR
888 if (GetType() == wxT("string") &&
889 m_data->GetRefCount() == 1)
890 {
891 ((wxVariantDataString*)GetData())->SetValue(value);
892 }
893 else
894 {
895 UnRef();
896 m_data = new wxVariantDataString(value);
897 }
a0a302dc
JS
898}
899
2562c823 900void wxVariant::operator= (const wxChar* value)
a0a302dc 901{
2562c823
RR
902 if (GetType() == wxT("string") &&
903 m_data->GetRefCount() == 1)
904 {
905 ((wxVariantDataString*)GetData())->SetValue(wxString(value));
906 }
907 else
908 {
909 UnRef();
910 m_data = new wxVariantDataString(wxString(value));
911 }
a0a302dc
JS
912}
913
2562c823 914wxString wxVariant::GetString() const
a0a302dc 915{
2562c823
RR
916 wxString value;
917 if (!Convert(& value))
918 {
919 wxFAIL_MSG(wxT("Could not convert to a string"));
920 }
a0a302dc 921
2562c823 922 return value;
a0a302dc
JS
923}
924
2562c823
RR
925// ----------------------------------------------------------------------------
926// wxVariantDataWxObjectPtr
927// ----------------------------------------------------------------------------
cf6ae290
RG
928
929class wxVariantDataWxObjectPtr: public wxVariantData
930{
931DECLARE_DYNAMIC_CLASS(wxVariantDataWxObjectPtr)
932public:
933 wxVariantDataWxObjectPtr() { }
934 wxVariantDataWxObjectPtr(wxObject* value) { m_value = value; }
935
936 inline wxObject* GetValue() const { return m_value; }
937 inline void SetValue(wxObject* value) { m_value = value; }
938
cf6ae290
RG
939 virtual bool Eq(wxVariantData& data) const;
940#if wxUSE_STD_IOSTREAM
941 virtual bool Write(wxSTD ostream& str) const;
942#endif
943 virtual bool Write(wxString& str) const;
944#if wxUSE_STD_IOSTREAM
945 virtual bool Read(wxSTD istream& str);
946#endif
947 virtual bool Read(wxString& str);
948 virtual wxString GetType() const ;
949 virtual wxVariantData* Clone() { return new wxVariantDataWxObjectPtr; }
950
cab1a605 951 virtual wxClassInfo* GetValueClassInfo() ;
cf6ae290
RG
952protected:
953 wxObject* m_value;
954
955 DECLARE_NO_COPY_CLASS(wxVariantDataWxObjectPtr)
956};
957
958IMPLEMENT_DYNAMIC_CLASS(wxVariantDataWxObjectPtr, wxVariantData)
959
cf6ae290
RG
960bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const
961{
962 wxASSERT_MSG( wxIsKindOf((&data), wxVariantDataWxObjectPtr), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
963
964 wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
965
966 return (otherData.m_value == m_value);
967}
968
969wxString wxVariantDataWxObjectPtr::GetType() const
970{
971 wxString returnVal(wxT("wxObject"));
972 if (m_value) {
973 returnVal = m_value->GetClassInfo()->GetClassName();
974 }
975 return returnVal;
976}
977
978wxClassInfo* wxVariantDataWxObjectPtr::GetValueClassInfo()
979{
980 wxClassInfo* returnVal=NULL;
cab1a605
WS
981
982 if (m_value) returnVal = m_value->GetClassInfo();
cf6ae290
RG
983
984 return returnVal;
985}
986
987#if wxUSE_STD_IOSTREAM
988bool wxVariantDataWxObjectPtr::Write(wxSTD ostream& str) const
989{
990 wxString s;
991 Write(s);
992 str << (const char*) s.mb_str();
cab1a605 993 return true;
cf6ae290
RG
994}
995#endif
996
997bool wxVariantDataWxObjectPtr::Write(wxString& str) const
998{
d595fb29 999 str.Printf(wxT("%s(%p)"), GetType().c_str(), wx_static_cast(void*, m_value));
cab1a605 1000 return true;
cf6ae290
RG
1001}
1002
1003#if wxUSE_STD_IOSTREAM
1004bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
1005{
1006 // Not implemented
cab1a605 1007 return false;
cf6ae290
RG
1008}
1009#endif
1010
1011bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
1012{
1013 // Not implemented
cab1a605 1014 return false;
cf6ae290
RG
1015}
1016
2562c823 1017// wxVariant
cf6ae290 1018
2562c823
RR
1019wxVariant::wxVariant( wxObject* val, const wxString& name)
1020{
1021 m_data = new wxVariantDataWxObjectPtr(val);
1022 m_name = name;
1023}
edca7a82 1024
2562c823
RR
1025bool wxVariant::operator== (wxObject* value) const
1026{
1027 return (value == ((wxVariantDataWxObjectPtr*)GetData())->GetValue());
1028}
e2b87f38 1029
2562c823 1030bool wxVariant::operator!= (wxObject* value) const
edca7a82 1031{
2562c823
RR
1032 return (!((*this) == (wxObject*) value));
1033}
1034
1035void wxVariant::operator= (wxObject* value)
1036{
1037 UnRef();
1038 m_data = new wxVariantDataWxObjectPtr(value);
1039}
edca7a82 1040
2562c823
RR
1041wxObject* wxVariant::GetWxObjectPtr() const
1042{
1043 wxASSERT(wxIsKindOf(GetData(), wxVariantDataWxObjectPtr));
1044 return (wxObject*) ((wxVariantDataWxObjectPtr*) m_data)->GetValue();
1045}
1046
1047// ----------------------------------------------------------------------------
1048// wxVariantDataVoidPtr
1049// ----------------------------------------------------------------------------
1050
1051class wxVariantDataVoidPtr: public wxVariantData
1052{
1053DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
edca7a82 1054public:
2562c823
RR
1055 wxVariantDataVoidPtr() { }
1056 wxVariantDataVoidPtr(void* value) { m_value = value; }
edca7a82 1057
2562c823
RR
1058 inline void* GetValue() const { return m_value; }
1059 inline void SetValue(void* value) { m_value = value; }
edca7a82 1060
edca7a82
GT
1061 virtual bool Eq(wxVariantData& data) const;
1062#if wxUSE_STD_IOSTREAM
2b004197 1063 virtual bool Write(wxSTD ostream& str) const;
edca7a82
GT
1064#endif
1065 virtual bool Write(wxString& str) const;
1066#if wxUSE_STD_IOSTREAM
2b004197 1067 virtual bool Read(wxSTD istream& str);
edca7a82
GT
1068#endif
1069 virtual bool Read(wxString& str);
47b378bd 1070 virtual wxString GetType() const { return wxT("void*"); }
2562c823 1071 virtual wxVariantData* Clone() { return new wxVariantDataVoidPtr; }
edca7a82
GT
1072
1073protected:
2562c823 1074 void* m_value;
edca7a82 1075
2562c823
RR
1076 DECLARE_NO_COPY_CLASS(wxVariantDataVoidPtr)
1077};
edca7a82 1078
2562c823 1079IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
edca7a82 1080
2562c823 1081bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
edca7a82 1082{
2562c823 1083 wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
edca7a82 1084
2562c823 1085 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
edca7a82 1086
2562c823 1087 return (otherData.m_value == m_value);
edca7a82
GT
1088}
1089
2562c823
RR
1090#if wxUSE_STD_IOSTREAM
1091bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
edca7a82 1092{
2562c823
RR
1093 wxString s;
1094 Write(s);
1095 str << (const char*) s.mb_str();
1096 return true;
edca7a82 1097}
2562c823 1098#endif
edca7a82 1099
2562c823
RR
1100bool wxVariantDataVoidPtr::Write(wxString& str) const
1101{
1102 str.Printf(wxT("%p"), m_value);
1103 return true;
1104}
edca7a82
GT
1105
1106#if wxUSE_STD_IOSTREAM
2562c823 1107bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
edca7a82
GT
1108{
1109 // Not implemented
cab1a605 1110 return false;
edca7a82
GT
1111}
1112#endif
1113
2562c823 1114bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
edca7a82 1115{
2562c823
RR
1116 // Not implemented
1117 return false;
edca7a82
GT
1118}
1119
2562c823 1120// wxVariant
edca7a82 1121
2562c823 1122wxVariant::wxVariant( void* val, const wxString& name)
edca7a82 1123{
2562c823
RR
1124 m_data = new wxVariantDataVoidPtr(val);
1125 m_name = name;
1126}
1127
1128bool wxVariant::operator== (void* value) const
1129{
1130 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
edca7a82 1131}
edca7a82 1132
2562c823
RR
1133bool wxVariant::operator!= (void* value) const
1134{
1135 return (!((*this) == (void*) value));
1136}
edca7a82 1137
2562c823 1138void wxVariant::operator= (void* value)
edca7a82 1139{
2562c823
RR
1140 if (GetType() == wxT("void*") &&
1141 m_data->GetRefCount() == 1)
1142 {
1143 ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1144 }
1145 else
1146 {
1147 UnRef();
1148 m_data = new wxVariantDataVoidPtr(value);
1149 }
edca7a82
GT
1150}
1151
2562c823
RR
1152void* wxVariant::GetVoidPtr() const
1153{
1154 wxASSERT( (GetType() == wxT("void*")) );
1155
1156 return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
1157}
e2b87f38 1158
fb42d7c3 1159// ----------------------------------------------------------------------------
2562c823 1160// wxVariantDataDateTime
fb42d7c3
VZ
1161// ----------------------------------------------------------------------------
1162
2562c823
RR
1163#if wxUSE_DATETIME
1164
1165class wxVariantDataDateTime: public wxVariantData
fb42d7c3 1166{
2562c823
RR
1167 DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime)
1168
fb42d7c3 1169public:
2562c823
RR
1170 wxVariantDataDateTime() { }
1171 wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
1172#if wxUSE_ODBC
1173 wxVariantDataDateTime(const TIME_STRUCT* valptr)
1174 { m_value = wxDateTime(valptr->hour, valptr->minute, valptr->second); }
1175 wxVariantDataDateTime(const DATE_STRUCT* valptr)
1176 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1),valptr->year); }
1177 wxVariantDataDateTime(const TIMESTAMP_STRUCT* valptr)
1178 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1), valptr->year,
1179 valptr->hour, valptr->minute, valptr->second, (wxDateTime::wxDateTime_t)valptr->fraction ); }
1180#endif //ODBC
fb42d7c3 1181
2562c823
RR
1182 inline wxDateTime GetValue() const { return m_value; }
1183 inline void SetValue(const wxDateTime& value) { m_value = value; }
fb42d7c3 1184
fb42d7c3
VZ
1185 virtual bool Eq(wxVariantData& data) const;
1186#if wxUSE_STD_IOSTREAM
1187 virtual bool Write(wxSTD ostream& str) const;
1188#endif
1189 virtual bool Write(wxString& str) const;
1190#if wxUSE_STD_IOSTREAM
1191 virtual bool Read(wxSTD istream& str);
1192#endif
1193 virtual bool Read(wxString& str);
47b378bd 1194 virtual wxString GetType() const { return wxT("datetime"); }
2562c823 1195 virtual wxVariantData* Clone() { return new wxVariantDataDateTime; }
fb42d7c3
VZ
1196
1197protected:
2562c823 1198 wxDateTime m_value;
fb42d7c3
VZ
1199};
1200
fb42d7c3 1201
2562c823 1202IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime, wxVariantData)
fb42d7c3 1203
2562c823 1204bool wxVariantDataDateTime::Eq(wxVariantData& data) const
fb42d7c3 1205{
2562c823 1206 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
fb42d7c3 1207
2562c823 1208 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
fb42d7c3 1209
2562c823 1210 return (otherData.m_value == m_value);
fb42d7c3
VZ
1211}
1212
1213
1214#if wxUSE_STD_IOSTREAM
2562c823 1215bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
fb42d7c3 1216{
2562c823
RR
1217 wxString value;
1218 Write( value );
1219 str << value.c_str();
1220 return true;
fb42d7c3
VZ
1221}
1222#endif
1223
1224
2562c823 1225bool wxVariantDataDateTime::Write(wxString& str) const
fb42d7c3 1226{
2562c823 1227 str = m_value.Format();
cab1a605 1228 return true;
fb42d7c3
VZ
1229}
1230
1231
1232#if wxUSE_STD_IOSTREAM
2562c823 1233bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
fb42d7c3
VZ
1234{
1235 // Not implemented
cab1a605 1236 return false;
fb42d7c3
VZ
1237}
1238#endif
1239
1240
2562c823 1241bool wxVariantDataDateTime::Read(wxString& str)
fb42d7c3 1242{
52de37c7 1243 if(! m_value.ParseDateTime(str.c_str()/*FIXME-UTF8*/))
2562c823 1244 return false;
cab1a605 1245 return true;
fb42d7c3
VZ
1246}
1247
2562c823 1248// wxVariant
fb42d7c3 1249
ff818ab8
RG
1250wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1251{
cab1a605
WS
1252 m_data = new wxVariantDataDateTime(val);
1253 m_name = name;
ff818ab8 1254}
ff818ab8 1255
edca7a82
GT
1256#if wxUSE_ODBC
1257wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1258{
1259 m_data = new wxVariantDataDateTime(valptr);
1260 m_name = name;
1261}
1262
1263wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1264{
1265 m_data = new wxVariantDataDateTime(valptr);
1266 m_name = name;
1267}
1268
1269wxVariant::wxVariant(const DATE_STRUCT* valptr, const wxString& name) // Date
1270{
1271 m_data = new wxVariantDataDateTime(valptr);
1272 m_name = name;
1273}
fb42d7c3
VZ
1274#endif // wxUSE_ODBC
1275
2562c823 1276bool wxVariant::operator== (const wxDateTime& value) const
fb42d7c3 1277{
2562c823
RR
1278 wxDateTime thisValue;
1279 if (!Convert(&thisValue))
1280 return false;
1281
1282 return value.IsEqualTo(thisValue);
fb42d7c3 1283}
edca7a82 1284
2562c823 1285bool wxVariant::operator!= (const wxDateTime& value) const
341287bf 1286{
2562c823
RR
1287 return (!((*this) == value));
1288}
1289
1290void wxVariant::operator= (const wxDateTime& value)
1291{
1292 if (GetType() == wxT("datetime") &&
1293 m_data->GetRefCount() == 1)
341287bf 1294 {
2562c823 1295 ((wxVariantDataDateTime*)GetData())->SetValue(value);
341287bf 1296 }
4fabb575 1297 else
2562c823
RR
1298 {
1299 UnRef();
1300 m_data = new wxVariantDataDateTime(value);
1301 }
341287bf
JS
1302}
1303
2562c823
RR
1304#if wxUSE_ODBC
1305void wxVariant::operator= (const DATE_STRUCT* value)
341287bf 1306{
2562c823
RR
1307 UnRef();
1308 m_data = new wxVariantDataDateTime(value);
341287bf
JS
1309}
1310
2562c823 1311void wxVariant::operator= (const TIME_STRUCT* value)
341287bf 1312{
2562c823
RR
1313 UnRef();
1314 m_data = new wxVariantDataDateTime(value);
341287bf
JS
1315}
1316
2562c823 1317void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
341287bf 1318{
2562c823
RR
1319 UnRef();
1320 m_data = new wxVariantDataDateTime(value);
341287bf
JS
1321}
1322
2562c823 1323#endif // wxUSE_ODBC
341287bf 1324
2562c823
RR
1325wxDateTime wxVariant::GetDateTime() const
1326{
1327 wxDateTime value;
1328 if (!Convert(& value))
341287bf 1329 {
2562c823 1330 wxFAIL_MSG(wxT("Could not convert to a datetime"));
341287bf 1331 }
3d8daa0f 1332
2562c823 1333 return value;
341287bf
JS
1334}
1335
2562c823 1336#endif // wxUSE_DATETIME
341287bf 1337
2562c823
RR
1338// ----------------------------------------------------------------------------
1339// wxVariantDataArrayString
1340// ----------------------------------------------------------------------------
1341
1342class wxVariantDataArrayString: public wxVariantData
341287bf 1343{
2562c823
RR
1344public:
1345 wxVariantDataArrayString() { }
1346 wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
341287bf 1347
2562c823
RR
1348 wxArrayString GetValue() const { return m_value; }
1349 void SetValue(const wxArrayString& value) { m_value = value; }
341287bf 1350
2562c823
RR
1351 virtual bool Eq(wxVariantData& data) const;
1352#if wxUSE_STD_IOSTREAM
1353 virtual bool Write(wxSTD ostream& str) const;
1354#endif
1355 virtual bool Write(wxString& str) const;
1356#if wxUSE_STD_IOSTREAM
1357 virtual bool Read(wxSTD istream& str);
1358#endif
1359 virtual bool Read(wxString& str);
47b378bd 1360 virtual wxString GetType() const { return wxT("arrstring"); }
2562c823 1361 virtual wxVariantData* Clone() { return new wxVariantDataArrayString; }
341287bf 1362
2562c823
RR
1363protected:
1364 wxArrayString m_value;
341287bf 1365
2562c823
RR
1366 DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString)
1367};
bc14c8b2 1368
2562c823 1369IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString, wxVariantData)
341287bf 1370
2562c823 1371bool wxVariantDataArrayString::Eq(wxVariantData& data) const
341287bf 1372{
2562c823 1373 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
341287bf 1374
2562c823 1375 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
341287bf 1376
2562c823 1377 return otherData.m_value == m_value;
341287bf
JS
1378}
1379
2562c823
RR
1380#if wxUSE_STD_IOSTREAM
1381bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
341287bf 1382{
2562c823
RR
1383 // Not implemented
1384 return false;
341287bf 1385}
2562c823 1386#endif
341287bf 1387
2562c823 1388bool wxVariantDataArrayString::Write(wxString& str) const
341287bf 1389{
2562c823
RR
1390 size_t count = m_value.GetCount();
1391 for ( size_t n = 0; n < count; n++ )
341287bf 1392 {
2562c823
RR
1393 if ( n )
1394 str += _T(';');
1395
1396 str += m_value[n];
341287bf 1397 }
341287bf 1398
2562c823 1399 return true;
341287bf
JS
1400}
1401
2562c823
RR
1402
1403#if wxUSE_STD_IOSTREAM
1404bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
341287bf 1405{
2562c823
RR
1406 // Not implemented
1407 return false;
341287bf 1408}
2562c823 1409#endif
341287bf 1410
2562c823
RR
1411
1412bool wxVariantDataArrayString::Read(wxString& str)
341287bf 1413{
2562c823
RR
1414 wxStringTokenizer tk(str, _T(";"));
1415 while ( tk.HasMoreTokens() )
341287bf 1416 {
2562c823 1417 m_value.Add(tk.GetNextToken());
341287bf 1418 }
341287bf 1419
2562c823 1420 return true;
341287bf
JS
1421}
1422
2562c823
RR
1423// wxVariant
1424
1425wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1426{
1427 m_data = new wxVariantDataArrayString(val);
1428 m_name = name;
341287bf
JS
1429}
1430
2562c823 1431bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
341287bf 1432{
2562c823 1433 wxFAIL_MSG( _T("TODO") );
f6bcfd97 1434
2562c823 1435 return false;
341287bf
JS
1436}
1437
2562c823 1438bool wxVariant::operator!=(const wxArrayString& value) const
341287bf 1439{
2562c823 1440 return !(*this == value);
341287bf
JS
1441}
1442
2562c823 1443void wxVariant::operator=(const wxArrayString& value)
341287bf 1444{
2562c823
RR
1445 if (GetType() == wxT("arrstring") &&
1446 m_data->GetRefCount() == 1)
341287bf 1447 {
2562c823 1448 ((wxVariantDataArrayString *)GetData())->SetValue(value);
341287bf
JS
1449 }
1450 else
1451 {
2562c823
RR
1452 UnRef();
1453 m_data = new wxVariantDataArrayString(value);
341287bf
JS
1454 }
1455}
1456
2562c823 1457wxArrayString wxVariant::GetArrayString() const
341287bf 1458{
2562c823
RR
1459 if ( GetType() == wxT("arrstring") )
1460 return ((wxVariantDataArrayString *)GetData())->GetValue();
1461
1462 return wxArrayString();
341287bf
JS
1463}
1464
2562c823
RR
1465// ----------------------------------------------------------------------------
1466// wxVariantDataList
1467// ----------------------------------------------------------------------------
2c3a1064 1468
2562c823 1469class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
341287bf 1470{
2562c823
RR
1471DECLARE_DYNAMIC_CLASS(wxVariantDataList)
1472public:
1473 wxVariantDataList() {}
1474 wxVariantDataList(const wxList& list);
1475 virtual ~wxVariantDataList();
341287bf 1476
2562c823
RR
1477 wxList& GetValue() { return m_value; }
1478 void SetValue(const wxList& value) ;
341287bf 1479
2562c823
RR
1480 virtual bool Eq(wxVariantData& data) const;
1481#if wxUSE_STD_IOSTREAM
1482 virtual bool Write(wxSTD ostream& str) const;
1483#endif
1484 virtual bool Write(wxString& str) const;
1485#if wxUSE_STD_IOSTREAM
1486 virtual bool Read(wxSTD istream& str);
1487#endif
1488 virtual bool Read(wxString& str);
47b378bd 1489 virtual wxString GetType() const { return wxT("list"); }
52e81242 1490
2562c823 1491 void Clear();
341287bf 1492
2562c823
RR
1493protected:
1494 wxList m_value;
1495};
341287bf 1496
2562c823 1497IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
2c3a1064 1498
2562c823 1499wxVariantDataList::wxVariantDataList(const wxList& list)
341287bf 1500{
2562c823 1501 SetValue(list);
341287bf
JS
1502}
1503
2562c823 1504wxVariantDataList::~wxVariantDataList()
341287bf 1505{
2562c823 1506 Clear();
341287bf
JS
1507}
1508
2562c823 1509void wxVariantDataList::SetValue(const wxList& value)
341287bf 1510{
2562c823
RR
1511 Clear();
1512 wxList::compatibility_iterator node = value.GetFirst();
1513 while (node)
341287bf 1514 {
2562c823
RR
1515 wxVariant* var = (wxVariant*) node->GetData();
1516 m_value.Append(new wxVariant(*var));
1517 node = node->GetNext();
341287bf 1518 }
2562c823
RR
1519}
1520
1521void wxVariantDataList::Clear()
1522{
1523 wxList::compatibility_iterator node = m_value.GetFirst();
1524 while (node)
341287bf 1525 {
2562c823
RR
1526 wxVariant* var = (wxVariant*) node->GetData();
1527 delete var;
1528 node = node->GetNext();
341287bf 1529 }
2562c823 1530 m_value.Clear();
341287bf
JS
1531}
1532
2562c823 1533bool wxVariantDataList::Eq(wxVariantData& data) const
a0a302dc 1534{
2562c823
RR
1535 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
1536
1537 wxVariantDataList& listData = (wxVariantDataList&) data;
1538 wxList::compatibility_iterator node1 = m_value.GetFirst();
1539 wxList::compatibility_iterator node2 = listData.GetValue().GetFirst();
1540 while (node1 && node2)
1541 {
1542 wxVariant* var1 = (wxVariant*) node1->GetData();
1543 wxVariant* var2 = (wxVariant*) node2->GetData();
1544 if ((*var1) != (*var2))
1545 return false;
1546 node1 = node1->GetNext();
1547 node2 = node2->GetNext();
1548 }
1549 if (node1 || node2) return false;
1550 return true;
a0a302dc
JS
1551}
1552
2562c823
RR
1553#if wxUSE_STD_IOSTREAM
1554bool wxVariantDataList::Write(wxSTD ostream& str) const
a0a302dc 1555{
2562c823
RR
1556 wxString s;
1557 Write(s);
1558 str << (const char*) s.mb_str();
1559 return true;
a0a302dc 1560}
2562c823 1561#endif
a0a302dc 1562
2562c823 1563bool wxVariantDataList::Write(wxString& str) const
a0a302dc 1564{
2562c823
RR
1565 str = wxEmptyString;
1566 wxList::compatibility_iterator node = m_value.GetFirst();
1567 while (node)
a0a302dc 1568 {
2562c823
RR
1569 wxVariant* var = (wxVariant*) node->GetData();
1570 if (node != m_value.GetFirst())
1571 str += wxT(" ");
1572 wxString str1;
1573 str += var->MakeString();
1574 node = node->GetNext();
a0a302dc 1575 }
2562c823
RR
1576
1577 return true;
a0a302dc 1578}
2f620946 1579
2562c823
RR
1580#if wxUSE_STD_IOSTREAM
1581bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
2f620946 1582{
2562c823
RR
1583 wxFAIL_MSG(wxT("Unimplemented"));
1584 // TODO
1585 return false;
2f620946 1586}
2562c823 1587#endif
2f620946 1588
2562c823 1589bool wxVariantDataList::Read(wxString& WXUNUSED(str))
2f620946 1590{
2562c823
RR
1591 wxFAIL_MSG(wxT("Unimplemented"));
1592 // TODO
1593 return false;
2f620946
RR
1594}
1595
2562c823
RR
1596// wxVariant
1597
1598wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
2f620946 1599{
2562c823
RR
1600 m_data = new wxVariantDataList(val);
1601 m_name = name;
2f620946 1602}
341287bf 1603
2562c823 1604bool wxVariant::operator== (const wxList& value) const
edca7a82 1605{
2562c823 1606 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
edca7a82 1607
2562c823
RR
1608 wxVariantDataList other(value);
1609 return (GetData()->Eq(other));
edca7a82
GT
1610}
1611
2562c823 1612bool wxVariant::operator!= (const wxList& value) const
edca7a82
GT
1613{
1614 return (!((*this) == value));
1615}
1616
2562c823 1617void wxVariant::operator= (const wxList& value)
edca7a82 1618{
2562c823
RR
1619 if (GetType() == wxT("list") &&
1620 m_data->GetRefCount() == 1)
edca7a82 1621 {
2562c823 1622 ((wxVariantDataList*)GetData())->SetValue(value);
edca7a82
GT
1623 }
1624 else
1625 {
2562c823
RR
1626 UnRef();
1627 m_data = new wxVariantDataList(value);
edca7a82
GT
1628 }
1629}
1630
2562c823 1631wxList& wxVariant::GetList() const
edca7a82 1632{
2562c823 1633 wxASSERT( (GetType() == wxT("list")) );
edca7a82 1634
2562c823
RR
1635 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1636}
edca7a82 1637
2562c823
RR
1638// Make empty list
1639void wxVariant::NullList()
edca7a82 1640{
2562c823 1641 SetData(new wxVariantDataList());
edca7a82
GT
1642}
1643
2562c823
RR
1644// Append to list
1645void wxVariant::Append(const wxVariant& value)
edca7a82 1646{
2562c823
RR
1647 wxList& list = GetList();
1648
1649 list.Append(new wxVariant(value));
edca7a82
GT
1650}
1651
2562c823
RR
1652// Insert at front of list
1653void wxVariant::Insert(const wxVariant& value)
1654{
1655 wxList& list = GetList();
fb42d7c3 1656
2562c823
RR
1657 list.Insert(new wxVariant(value));
1658}
1659
1660// Returns true if the variant is a member of the list
1661bool wxVariant::Member(const wxVariant& value) const
fb42d7c3 1662{
2562c823 1663 wxList& list = GetList();
fb42d7c3 1664
2562c823
RR
1665 wxList::compatibility_iterator node = list.GetFirst();
1666 while (node)
1667 {
1668 wxVariant* other = (wxVariant*) node->GetData();
1669 if (value == *other)
1670 return true;
1671 node = node->GetNext();
1672 }
cab1a605 1673 return false;
fb42d7c3
VZ
1674}
1675
2562c823
RR
1676// Deletes the nth element of the list
1677bool wxVariant::Delete(size_t item)
fb42d7c3 1678{
2562c823
RR
1679 wxList& list = GetList();
1680
1681 wxASSERT_MSG( (item < list.GetCount()), wxT("Invalid index to Delete") );
1682 wxList::compatibility_iterator node = list.Item(item);
1683 wxVariant* variant = (wxVariant*) node->GetData();
1684 delete variant;
1685 list.Erase(node);
1686 return true;
fb42d7c3
VZ
1687}
1688
2562c823
RR
1689// Clear list
1690void wxVariant::ClearList()
fb42d7c3 1691{
2562c823 1692 if (!IsNull() && (GetType() == wxT("list")))
fb42d7c3 1693 {
2562c823 1694 ((wxVariantDataList*) m_data)->Clear();
fb42d7c3
VZ
1695 }
1696 else
1697 {
2562c823
RR
1698 if (!GetType().IsSameAs(wxT("list")))
1699 UnRef();
fb42d7c3 1700
2562c823
RR
1701 m_data = new wxVariantDataList;
1702 }
fb42d7c3
VZ
1703}
1704
60acae80
RR
1705// Treat a list variant as an array
1706wxVariant wxVariant::operator[] (size_t idx) const
1707{
60acae80 1708 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
60acae80
RR
1709
1710 if (GetType() == wxT("list"))
1711 {
1712 wxVariantDataList* data = (wxVariantDataList*) m_data;
1713 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1714 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1715 }
60acae80
RR
1716 return wxNullVariant;
1717}
1718
1719wxVariant& wxVariant::operator[] (size_t idx)
1720{
1721 // We can't return a reference to a variant for a string list, since the string
1722 // is actually stored as a char*, not a variant.
1723
1724 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1725
1726 wxVariantDataList* data = (wxVariantDataList*) m_data;
1727 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1728
1729 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1730}
1731
1732// Return the number of elements in a list
1733size_t wxVariant::GetCount() const
1734{
60acae80 1735 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
60acae80
RR
1736
1737 if (GetType() == wxT("list"))
1738 {
1739 wxVariantDataList* data = (wxVariantDataList*) m_data;
1740 return data->GetValue().GetCount();
1741 }
60acae80
RR
1742 return 0;
1743}
1744
2562c823 1745// ----------------------------------------------------------------------------
341287bf 1746// Type conversion
2562c823
RR
1747// ----------------------------------------------------------------------------
1748
341287bf
JS
1749bool wxVariant::Convert(long* value) const
1750{
1751 wxString type(GetType());
223d09f6 1752 if (type == wxT("double"))
2562c823 1753 *value = (long) (((wxVariantDoubleData*)GetData())->GetValue());
223d09f6 1754 else if (type == wxT("long"))
341287bf 1755 *value = ((wxVariantDataLong*)GetData())->GetValue();
862416e0 1756#ifdef HAVE_BOOL
223d09f6 1757 else if (type == wxT("bool"))
341287bf 1758 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1759#endif
223d09f6 1760 else if (type == wxT("string"))
52de37c7 1761 *value = wxAtol(((wxVariantDataString*)GetData())->GetValue());
341287bf 1762 else
cab1a605 1763 return false;
341287bf 1764
cab1a605 1765 return true;
341287bf
JS
1766}
1767
1768bool wxVariant::Convert(bool* value) const
1769{
1770 wxString type(GetType());
223d09f6 1771 if (type == wxT("double"))
2562c823 1772 *value = ((int) (((wxVariantDoubleData*)GetData())->GetValue()) != 0);
223d09f6 1773 else if (type == wxT("long"))
341287bf 1774 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
862416e0 1775#ifdef HAVE_BOOL
223d09f6 1776 else if (type == wxT("bool"))
341287bf 1777 *value = ((wxVariantDataBool*)GetData())->GetValue();
862416e0 1778#endif
223d09f6 1779 else if (type == wxT("string"))
341287bf
JS
1780 {
1781 wxString val(((wxVariantDataString*)GetData())->GetValue());
1782 val.MakeLower();
b1638abf 1783 if (val == wxT("true") || val == wxT("yes") || val == wxT('1') )
cab1a605 1784 *value = true;
b1638abf 1785 else if (val == wxT("false") || val == wxT("no") || val == wxT('0') )
cab1a605 1786 *value = false;
341287bf 1787 else
cab1a605 1788 return false;
341287bf
JS
1789 }
1790 else
cab1a605 1791 return false;
341287bf 1792
cab1a605 1793 return true;
341287bf
JS
1794}
1795
1796bool wxVariant::Convert(double* value) const
1797{
1798 wxString type(GetType());
223d09f6 1799 if (type == wxT("double"))
2562c823 1800 *value = ((wxVariantDoubleData*)GetData())->GetValue();
223d09f6 1801 else if (type == wxT("long"))
341287bf 1802 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
862416e0 1803#ifdef HAVE_BOOL
223d09f6 1804 else if (type == wxT("bool"))
341287bf 1805 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1806#endif
223d09f6 1807 else if (type == wxT("string"))
52de37c7 1808 *value = (double) wxAtof(((wxVariantDataString*)GetData())->GetValue());
341287bf 1809 else
cab1a605 1810 return false;
341287bf 1811
cab1a605 1812 return true;
341287bf
JS
1813}
1814
38f82bf6 1815bool wxVariant::Convert(wxChar* value) const
341287bf
JS
1816{
1817 wxString type(GetType());
223d09f6 1818 if (type == wxT("char"))
341287bf 1819 *value = ((wxVariantDataChar*)GetData())->GetValue();
223d09f6 1820 else if (type == wxT("long"))
341287bf 1821 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
862416e0 1822#ifdef HAVE_BOOL
223d09f6 1823 else if (type == wxT("bool"))
341287bf 1824 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1825#endif
341287bf 1826 else
cab1a605 1827 return false;
341287bf 1828
cab1a605 1829 return true;
341287bf
JS
1830}
1831
1832bool wxVariant::Convert(wxString* value) const
1833{
1834 *value = MakeString();
cab1a605 1835 return true;
341287bf
JS
1836}
1837
e2b87f38 1838#if wxUSE_DATETIME
edca7a82
GT
1839bool wxVariant::Convert(wxDateTime* value) const
1840{
1841 wxString type(GetType());
1842 if (type == wxT("datetime"))
9708db20 1843 {
edca7a82 1844 *value = ((wxVariantDataDateTime*)GetData())->GetValue();
cab1a605 1845 return true;
dc259b79 1846 }
9708db20
JS
1847 // Fallback to string conversion
1848 wxString val;
9a8a9e99 1849 return Convert(&val) &&
52de37c7
VS
1850 (value->ParseDateTime(val.c_str()/*FIXME-UTF8*/) ||
1851 value->ParseDate(val.c_str()/*FIXME-UTF8*/) ||
1852 value->ParseTime(val.c_str()/*FIXME-UTF8*/));
edca7a82 1853}
b1e343f2 1854#endif // wxUSE_DATETIME
d5dc103f
VZ
1855
1856#endif // wxUSE_VARIANT