]> git.saurik.com Git - wxWidgets.git/blame - src/common/variant.cpp
no changes, just a typo fix
[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; }
af717fa8 646 wxVariantDataChar(const wxUniChar& value) { m_value = value; }
341287bf 647
af717fa8
VS
648 inline wxUniChar GetValue() const { return m_value; }
649 inline void SetValue(const wxUniChar& 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:
af717fa8 665 wxUniChar 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 681{
af717fa8 682 str << wxString(m_value);
cab1a605 683 return true;
341287bf 684}
38830220 685#endif
341287bf
JS
686
687bool wxVariantDataChar::Write(wxString& str) const
688{
af717fa8 689 str = m_value;
cab1a605 690 return true;
341287bf
JS
691}
692
38830220 693#if wxUSE_STD_IOSTREAM
dd107c50 694bool wxVariantDataChar::Read(wxSTD istream& WXUNUSED(str))
341287bf 695{
223d09f6 696 wxFAIL_MSG(wxT("Unimplemented"));
07502d73 697
cab1a605 698 return false;
341287bf 699}
38830220 700#endif
341287bf 701
e02afc7a 702#if wxUSE_STREAMS
1ccbb61a
VZ
703bool wxVariantDataChar::Write(wxOutputStream& str) const
704{
fae05df5
GL
705 wxTextOutputStream s(str);
706
af717fa8
VS
707 // FIXME-UTF8: this should be just "s << m_value;" after removal of
708 // ANSI build and addition of wxUniChar to wxTextOutputStream:
709 s << (wxChar)m_value;
07502d73 710
cab1a605 711 return true;
1ccbb61a
VZ
712}
713
75ed1d15
GL
714bool wxVariantDataChar::Read(wxInputStream& str)
715{
fae05df5
GL
716 wxTextInputStream s(str);
717
af717fa8
VS
718 // FIXME-UTF8: this should be just "s >> m_value;" after removal of
719 // ANSI build and addition of wxUniChar to wxTextInputStream:
720 wxChar ch;
721 s >> ch;
722 m_value = ch;
71520754 723
cab1a605 724 return true;
75ed1d15 725}
e02afc7a 726#endif // wxUSE_STREAMS
75ed1d15 727
341287bf
JS
728bool wxVariantDataChar::Read(wxString& str)
729{
af717fa8 730 m_value = str[0u];
cab1a605 731 return true;
341287bf
JS
732}
733
af717fa8 734wxVariant::wxVariant(const wxUniChar& val, const wxString& name)
2562c823
RR
735{
736 m_data = new wxVariantDataChar(val);
737 m_name = name;
738}
739
af717fa8 740wxVariant::wxVariant(char val, const wxString& name)
2562c823 741{
af717fa8
VS
742 m_data = new wxVariantDataChar(val);
743 m_name = name;
744}
745
746wxVariant::wxVariant(wchar_t val, const wxString& name)
747{
748 m_data = new wxVariantDataChar(val);
749 m_name = name;
750}
751
752bool wxVariant::operator==(const wxUniChar& value) const
753{
754 wxUniChar thisValue;
2562c823
RR
755 if (!Convert(&thisValue))
756 return false;
757 else
758 return (value == thisValue);
759}
760
af717fa8 761wxVariant& wxVariant::operator=(const wxUniChar& value)
2562c823
RR
762{
763 if (GetType() == wxT("char") &&
764 m_data->GetRefCount() == 1)
765 {
766 ((wxVariantDataChar*)GetData())->SetValue(value);
767 }
768 else
769 {
770 UnRef();
771 m_data = new wxVariantDataChar(value);
772 }
af717fa8
VS
773
774 return *this;
2562c823
RR
775}
776
af717fa8 777wxUniChar wxVariant::GetChar() const
2562c823 778{
af717fa8 779 wxUniChar value;
2562c823
RR
780 if (Convert(& value))
781 return value;
782 else
783 {
784 wxFAIL_MSG(wxT("Could not convert to a char"));
af717fa8 785 return wxUniChar(0);
2562c823
RR
786 }
787}
788
789// ----------------------------------------------------------------------------
790// wxVariantDataString
791// ----------------------------------------------------------------------------
341287bf 792
fd242375 793class WXDLLIMPEXP_BASE wxVariantDataString: public wxVariantData
341287bf
JS
794{
795DECLARE_DYNAMIC_CLASS(wxVariantDataString)
796public:
797 wxVariantDataString() { }
798 wxVariantDataString(const wxString& value) { m_value = value; }
799
800 inline wxString GetValue() const { return m_value; }
801 inline void SetValue(const wxString& value) { m_value = value; }
802
341287bf 803 virtual bool Eq(wxVariantData& data) const;
38830220 804#if wxUSE_STD_IOSTREAM
dd107c50 805 virtual bool Write(wxSTD ostream& str) const;
38830220 806#endif
1ccbb61a 807 virtual bool Read(wxString& str);
341287bf 808 virtual bool Write(wxString& str) const;
38830220 809#if wxUSE_STD_IOSTREAM
47b378bd 810 virtual bool Read(wxSTD istream& WXUNUSED(str)) { return false; }
38830220 811#endif
e02afc7a 812#if wxUSE_STREAMS
75ed1d15 813 virtual bool Read(wxInputStream& str);
1ccbb61a 814 virtual bool Write(wxOutputStream& str) const;
e02afc7a 815#endif // wxUSE_STREAMS
47b378bd 816 virtual wxString GetType() const { return wxT("string"); }
341287bf
JS
817
818protected:
819 wxString m_value;
820};
821
341287bf
JS
822bool wxVariantDataString::Eq(wxVariantData& data) const
823{
223d09f6 824 wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
341287bf
JS
825
826 wxVariantDataString& otherData = (wxVariantDataString&) data;
827
828 return (otherData.m_value == m_value);
829}
830
38830220 831#if wxUSE_STD_IOSTREAM
dd107c50 832bool wxVariantDataString::Write(wxSTD ostream& str) const
341287bf 833{
783b6cfd 834 str << (const char*) m_value.mb_str();
cab1a605 835 return true;
341287bf 836}
38830220 837#endif
341287bf
JS
838
839bool wxVariantDataString::Write(wxString& str) const
840{
841 str = m_value;
cab1a605 842 return true;
341287bf
JS
843}
844
e02afc7a 845#if wxUSE_STREAMS
1ccbb61a
VZ
846bool wxVariantDataString::Write(wxOutputStream& str) const
847{
783b6cfd 848 // why doesn't wxOutputStream::operator<< take "const wxString&"
fae05df5
GL
849 wxTextOutputStream s(str);
850 s.WriteString(m_value);
cab1a605 851 return true;
1ccbb61a
VZ
852}
853
75ed1d15
GL
854bool wxVariantDataString::Read(wxInputStream& str)
855{
fae05df5
GL
856 wxTextInputStream s(str);
857
40ff126a 858 m_value = s.ReadLine();
cab1a605 859 return true;
75ed1d15 860}
e02afc7a 861#endif // wxUSE_STREAMS
75ed1d15 862
341287bf
JS
863bool wxVariantDataString::Read(wxString& str)
864{
865 m_value = str;
cab1a605 866 return true;
341287bf
JS
867}
868
869IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
870
2562c823 871// wxVariant ****
07502d73 872
2562c823 873wxVariant::wxVariant(const wxString& val, const wxString& name)
a0a302dc 874{
2562c823
RR
875 m_data = new wxVariantDataString(val);
876 m_name = name;
877}
a0a302dc 878
af717fa8
VS
879wxVariant::wxVariant(const char* val, const wxString& name)
880{
881 m_data = new wxVariantDataString(wxString(val));
882 m_name = name;
883}
884
885wxVariant::wxVariant(const wchar_t* val, const wxString& name)
886{
887 m_data = new wxVariantDataString(wxString(val));
888 m_name = name;
889}
890
891wxVariant::wxVariant(const wxCStrData& val, const wxString& name)
892{
893 m_data = new wxVariantDataString(val.AsString());
894 m_name = name;
895}
896
897wxVariant::wxVariant(const wxCharBuffer& val, const wxString& name)
898{
899 m_data = new wxVariantDataString(wxString(val));
900 m_name = name;
901}
902
903wxVariant::wxVariant(const wxWCharBuffer& val, const wxString& name)
a0a302dc 904{
2562c823
RR
905 m_data = new wxVariantDataString(wxString(val));
906 m_name = name;
907}
a0a302dc 908
2562c823
RR
909bool wxVariant::operator== (const wxString& value) const
910{
911 wxString thisValue;
912 if (!Convert(&thisValue))
913 return false;
a0a302dc 914
2562c823 915 return value == thisValue;
a0a302dc
JS
916}
917
2562c823 918bool wxVariant::operator!= (const wxString& value) const
a0a302dc 919{
2562c823 920 return (!((*this) == value));
a0a302dc
JS
921}
922
af717fa8 923wxVariant& wxVariant::operator= (const wxString& value)
a0a302dc 924{
2562c823
RR
925 if (GetType() == wxT("string") &&
926 m_data->GetRefCount() == 1)
927 {
928 ((wxVariantDataString*)GetData())->SetValue(value);
929 }
930 else
931 {
932 UnRef();
933 m_data = new wxVariantDataString(value);
934 }
af717fa8 935 return *this;
a0a302dc
JS
936}
937
2562c823 938wxString wxVariant::GetString() const
a0a302dc 939{
2562c823
RR
940 wxString value;
941 if (!Convert(& value))
942 {
943 wxFAIL_MSG(wxT("Could not convert to a string"));
944 }
a0a302dc 945
2562c823 946 return value;
a0a302dc
JS
947}
948
2562c823
RR
949// ----------------------------------------------------------------------------
950// wxVariantDataWxObjectPtr
951// ----------------------------------------------------------------------------
cf6ae290
RG
952
953class wxVariantDataWxObjectPtr: public wxVariantData
954{
955DECLARE_DYNAMIC_CLASS(wxVariantDataWxObjectPtr)
956public:
957 wxVariantDataWxObjectPtr() { }
958 wxVariantDataWxObjectPtr(wxObject* value) { m_value = value; }
959
960 inline wxObject* GetValue() const { return m_value; }
961 inline void SetValue(wxObject* value) { m_value = value; }
962
cf6ae290
RG
963 virtual bool Eq(wxVariantData& data) const;
964#if wxUSE_STD_IOSTREAM
965 virtual bool Write(wxSTD ostream& str) const;
966#endif
967 virtual bool Write(wxString& str) const;
968#if wxUSE_STD_IOSTREAM
969 virtual bool Read(wxSTD istream& str);
970#endif
971 virtual bool Read(wxString& str);
972 virtual wxString GetType() const ;
973 virtual wxVariantData* Clone() { return new wxVariantDataWxObjectPtr; }
974
cab1a605 975 virtual wxClassInfo* GetValueClassInfo() ;
cf6ae290
RG
976protected:
977 wxObject* m_value;
978
979 DECLARE_NO_COPY_CLASS(wxVariantDataWxObjectPtr)
980};
981
982IMPLEMENT_DYNAMIC_CLASS(wxVariantDataWxObjectPtr, wxVariantData)
983
cf6ae290
RG
984bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const
985{
986 wxASSERT_MSG( wxIsKindOf((&data), wxVariantDataWxObjectPtr), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
987
988 wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
989
990 return (otherData.m_value == m_value);
991}
992
993wxString wxVariantDataWxObjectPtr::GetType() const
994{
995 wxString returnVal(wxT("wxObject"));
996 if (m_value) {
997 returnVal = m_value->GetClassInfo()->GetClassName();
998 }
999 return returnVal;
1000}
1001
1002wxClassInfo* wxVariantDataWxObjectPtr::GetValueClassInfo()
1003{
1004 wxClassInfo* returnVal=NULL;
cab1a605
WS
1005
1006 if (m_value) returnVal = m_value->GetClassInfo();
cf6ae290
RG
1007
1008 return returnVal;
1009}
1010
1011#if wxUSE_STD_IOSTREAM
1012bool wxVariantDataWxObjectPtr::Write(wxSTD ostream& str) const
1013{
1014 wxString s;
1015 Write(s);
1016 str << (const char*) s.mb_str();
cab1a605 1017 return true;
cf6ae290
RG
1018}
1019#endif
1020
1021bool wxVariantDataWxObjectPtr::Write(wxString& str) const
1022{
d595fb29 1023 str.Printf(wxT("%s(%p)"), GetType().c_str(), wx_static_cast(void*, m_value));
cab1a605 1024 return true;
cf6ae290
RG
1025}
1026
1027#if wxUSE_STD_IOSTREAM
1028bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
1029{
1030 // Not implemented
cab1a605 1031 return false;
cf6ae290
RG
1032}
1033#endif
1034
1035bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
1036{
1037 // Not implemented
cab1a605 1038 return false;
cf6ae290
RG
1039}
1040
2562c823 1041// wxVariant
cf6ae290 1042
2562c823
RR
1043wxVariant::wxVariant( wxObject* val, const wxString& name)
1044{
1045 m_data = new wxVariantDataWxObjectPtr(val);
1046 m_name = name;
1047}
edca7a82 1048
2562c823
RR
1049bool wxVariant::operator== (wxObject* value) const
1050{
1051 return (value == ((wxVariantDataWxObjectPtr*)GetData())->GetValue());
1052}
e2b87f38 1053
2562c823 1054bool wxVariant::operator!= (wxObject* value) const
edca7a82 1055{
2562c823
RR
1056 return (!((*this) == (wxObject*) value));
1057}
1058
1059void wxVariant::operator= (wxObject* value)
1060{
1061 UnRef();
1062 m_data = new wxVariantDataWxObjectPtr(value);
1063}
edca7a82 1064
2562c823
RR
1065wxObject* wxVariant::GetWxObjectPtr() const
1066{
1067 wxASSERT(wxIsKindOf(GetData(), wxVariantDataWxObjectPtr));
1068 return (wxObject*) ((wxVariantDataWxObjectPtr*) m_data)->GetValue();
1069}
1070
1071// ----------------------------------------------------------------------------
1072// wxVariantDataVoidPtr
1073// ----------------------------------------------------------------------------
1074
1075class wxVariantDataVoidPtr: public wxVariantData
1076{
1077DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
edca7a82 1078public:
2562c823
RR
1079 wxVariantDataVoidPtr() { }
1080 wxVariantDataVoidPtr(void* value) { m_value = value; }
edca7a82 1081
2562c823
RR
1082 inline void* GetValue() const { return m_value; }
1083 inline void SetValue(void* value) { m_value = value; }
edca7a82 1084
edca7a82
GT
1085 virtual bool Eq(wxVariantData& data) const;
1086#if wxUSE_STD_IOSTREAM
2b004197 1087 virtual bool Write(wxSTD ostream& str) const;
edca7a82
GT
1088#endif
1089 virtual bool Write(wxString& str) const;
1090#if wxUSE_STD_IOSTREAM
2b004197 1091 virtual bool Read(wxSTD istream& str);
edca7a82
GT
1092#endif
1093 virtual bool Read(wxString& str);
47b378bd 1094 virtual wxString GetType() const { return wxT("void*"); }
2562c823 1095 virtual wxVariantData* Clone() { return new wxVariantDataVoidPtr; }
edca7a82
GT
1096
1097protected:
2562c823 1098 void* m_value;
edca7a82 1099
2562c823
RR
1100 DECLARE_NO_COPY_CLASS(wxVariantDataVoidPtr)
1101};
edca7a82 1102
2562c823 1103IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
edca7a82 1104
2562c823 1105bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
edca7a82 1106{
2562c823 1107 wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
edca7a82 1108
2562c823 1109 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
edca7a82 1110
2562c823 1111 return (otherData.m_value == m_value);
edca7a82
GT
1112}
1113
2562c823
RR
1114#if wxUSE_STD_IOSTREAM
1115bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
edca7a82 1116{
2562c823
RR
1117 wxString s;
1118 Write(s);
1119 str << (const char*) s.mb_str();
1120 return true;
edca7a82 1121}
2562c823 1122#endif
edca7a82 1123
2562c823
RR
1124bool wxVariantDataVoidPtr::Write(wxString& str) const
1125{
1126 str.Printf(wxT("%p"), m_value);
1127 return true;
1128}
edca7a82
GT
1129
1130#if wxUSE_STD_IOSTREAM
2562c823 1131bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
edca7a82
GT
1132{
1133 // Not implemented
cab1a605 1134 return false;
edca7a82
GT
1135}
1136#endif
1137
2562c823 1138bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
edca7a82 1139{
2562c823
RR
1140 // Not implemented
1141 return false;
edca7a82
GT
1142}
1143
2562c823 1144// wxVariant
edca7a82 1145
2562c823 1146wxVariant::wxVariant( void* val, const wxString& name)
edca7a82 1147{
2562c823
RR
1148 m_data = new wxVariantDataVoidPtr(val);
1149 m_name = name;
1150}
1151
1152bool wxVariant::operator== (void* value) const
1153{
1154 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
edca7a82 1155}
edca7a82 1156
2562c823
RR
1157bool wxVariant::operator!= (void* value) const
1158{
1159 return (!((*this) == (void*) value));
1160}
edca7a82 1161
2562c823 1162void wxVariant::operator= (void* value)
edca7a82 1163{
2562c823
RR
1164 if (GetType() == wxT("void*") &&
1165 m_data->GetRefCount() == 1)
1166 {
1167 ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1168 }
1169 else
1170 {
1171 UnRef();
1172 m_data = new wxVariantDataVoidPtr(value);
1173 }
edca7a82
GT
1174}
1175
2562c823
RR
1176void* wxVariant::GetVoidPtr() const
1177{
1178 wxASSERT( (GetType() == wxT("void*")) );
1179
1180 return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
1181}
e2b87f38 1182
fb42d7c3 1183// ----------------------------------------------------------------------------
2562c823 1184// wxVariantDataDateTime
fb42d7c3
VZ
1185// ----------------------------------------------------------------------------
1186
2562c823
RR
1187#if wxUSE_DATETIME
1188
1189class wxVariantDataDateTime: public wxVariantData
fb42d7c3 1190{
2562c823
RR
1191 DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime)
1192
fb42d7c3 1193public:
2562c823
RR
1194 wxVariantDataDateTime() { }
1195 wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
1196#if wxUSE_ODBC
1197 wxVariantDataDateTime(const TIME_STRUCT* valptr)
1198 { m_value = wxDateTime(valptr->hour, valptr->minute, valptr->second); }
1199 wxVariantDataDateTime(const DATE_STRUCT* valptr)
1200 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1),valptr->year); }
1201 wxVariantDataDateTime(const TIMESTAMP_STRUCT* valptr)
1202 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1), valptr->year,
1203 valptr->hour, valptr->minute, valptr->second, (wxDateTime::wxDateTime_t)valptr->fraction ); }
1204#endif //ODBC
fb42d7c3 1205
2562c823
RR
1206 inline wxDateTime GetValue() const { return m_value; }
1207 inline void SetValue(const wxDateTime& value) { m_value = value; }
fb42d7c3 1208
fb42d7c3
VZ
1209 virtual bool Eq(wxVariantData& data) const;
1210#if wxUSE_STD_IOSTREAM
1211 virtual bool Write(wxSTD ostream& str) const;
1212#endif
1213 virtual bool Write(wxString& str) const;
1214#if wxUSE_STD_IOSTREAM
1215 virtual bool Read(wxSTD istream& str);
1216#endif
1217 virtual bool Read(wxString& str);
47b378bd 1218 virtual wxString GetType() const { return wxT("datetime"); }
2562c823 1219 virtual wxVariantData* Clone() { return new wxVariantDataDateTime; }
fb42d7c3
VZ
1220
1221protected:
2562c823 1222 wxDateTime m_value;
fb42d7c3
VZ
1223};
1224
fb42d7c3 1225
2562c823 1226IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime, wxVariantData)
fb42d7c3 1227
2562c823 1228bool wxVariantDataDateTime::Eq(wxVariantData& data) const
fb42d7c3 1229{
2562c823 1230 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
fb42d7c3 1231
2562c823 1232 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
fb42d7c3 1233
2562c823 1234 return (otherData.m_value == m_value);
fb42d7c3
VZ
1235}
1236
1237
1238#if wxUSE_STD_IOSTREAM
2562c823 1239bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
fb42d7c3 1240{
2562c823
RR
1241 wxString value;
1242 Write( value );
1243 str << value.c_str();
1244 return true;
fb42d7c3
VZ
1245}
1246#endif
1247
1248
2562c823 1249bool wxVariantDataDateTime::Write(wxString& str) const
fb42d7c3 1250{
2562c823 1251 str = m_value.Format();
cab1a605 1252 return true;
fb42d7c3
VZ
1253}
1254
1255
1256#if wxUSE_STD_IOSTREAM
2562c823 1257bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
fb42d7c3
VZ
1258{
1259 // Not implemented
cab1a605 1260 return false;
fb42d7c3
VZ
1261}
1262#endif
1263
1264
2562c823 1265bool wxVariantDataDateTime::Read(wxString& str)
fb42d7c3 1266{
52de37c7 1267 if(! m_value.ParseDateTime(str.c_str()/*FIXME-UTF8*/))
2562c823 1268 return false;
cab1a605 1269 return true;
fb42d7c3
VZ
1270}
1271
2562c823 1272// wxVariant
fb42d7c3 1273
ff818ab8
RG
1274wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1275{
cab1a605
WS
1276 m_data = new wxVariantDataDateTime(val);
1277 m_name = name;
ff818ab8 1278}
ff818ab8 1279
edca7a82
GT
1280#if wxUSE_ODBC
1281wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1282{
1283 m_data = new wxVariantDataDateTime(valptr);
1284 m_name = name;
1285}
1286
1287wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1288{
1289 m_data = new wxVariantDataDateTime(valptr);
1290 m_name = name;
1291}
1292
1293wxVariant::wxVariant(const DATE_STRUCT* valptr, const wxString& name) // Date
1294{
1295 m_data = new wxVariantDataDateTime(valptr);
1296 m_name = name;
1297}
fb42d7c3
VZ
1298#endif // wxUSE_ODBC
1299
2562c823 1300bool wxVariant::operator== (const wxDateTime& value) const
fb42d7c3 1301{
2562c823
RR
1302 wxDateTime thisValue;
1303 if (!Convert(&thisValue))
1304 return false;
1305
1306 return value.IsEqualTo(thisValue);
fb42d7c3 1307}
edca7a82 1308
2562c823 1309bool wxVariant::operator!= (const wxDateTime& value) const
341287bf 1310{
2562c823
RR
1311 return (!((*this) == value));
1312}
1313
1314void wxVariant::operator= (const wxDateTime& value)
1315{
1316 if (GetType() == wxT("datetime") &&
1317 m_data->GetRefCount() == 1)
341287bf 1318 {
2562c823 1319 ((wxVariantDataDateTime*)GetData())->SetValue(value);
341287bf 1320 }
4fabb575 1321 else
2562c823
RR
1322 {
1323 UnRef();
1324 m_data = new wxVariantDataDateTime(value);
1325 }
341287bf
JS
1326}
1327
2562c823
RR
1328#if wxUSE_ODBC
1329void wxVariant::operator= (const DATE_STRUCT* value)
341287bf 1330{
2562c823
RR
1331 UnRef();
1332 m_data = new wxVariantDataDateTime(value);
341287bf
JS
1333}
1334
2562c823 1335void wxVariant::operator= (const TIME_STRUCT* value)
341287bf 1336{
2562c823
RR
1337 UnRef();
1338 m_data = new wxVariantDataDateTime(value);
341287bf
JS
1339}
1340
2562c823 1341void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
341287bf 1342{
2562c823
RR
1343 UnRef();
1344 m_data = new wxVariantDataDateTime(value);
341287bf
JS
1345}
1346
2562c823 1347#endif // wxUSE_ODBC
341287bf 1348
2562c823
RR
1349wxDateTime wxVariant::GetDateTime() const
1350{
1351 wxDateTime value;
1352 if (!Convert(& value))
341287bf 1353 {
2562c823 1354 wxFAIL_MSG(wxT("Could not convert to a datetime"));
341287bf 1355 }
3d8daa0f 1356
2562c823 1357 return value;
341287bf
JS
1358}
1359
2562c823 1360#endif // wxUSE_DATETIME
341287bf 1361
2562c823
RR
1362// ----------------------------------------------------------------------------
1363// wxVariantDataArrayString
1364// ----------------------------------------------------------------------------
1365
1366class wxVariantDataArrayString: public wxVariantData
341287bf 1367{
2562c823
RR
1368public:
1369 wxVariantDataArrayString() { }
1370 wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
341287bf 1371
2562c823
RR
1372 wxArrayString GetValue() const { return m_value; }
1373 void SetValue(const wxArrayString& value) { m_value = value; }
341287bf 1374
2562c823
RR
1375 virtual bool Eq(wxVariantData& data) const;
1376#if wxUSE_STD_IOSTREAM
1377 virtual bool Write(wxSTD ostream& str) const;
1378#endif
1379 virtual bool Write(wxString& str) const;
1380#if wxUSE_STD_IOSTREAM
1381 virtual bool Read(wxSTD istream& str);
1382#endif
1383 virtual bool Read(wxString& str);
47b378bd 1384 virtual wxString GetType() const { return wxT("arrstring"); }
2562c823 1385 virtual wxVariantData* Clone() { return new wxVariantDataArrayString; }
341287bf 1386
2562c823
RR
1387protected:
1388 wxArrayString m_value;
341287bf 1389
2562c823
RR
1390 DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString)
1391};
bc14c8b2 1392
2562c823 1393IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString, wxVariantData)
341287bf 1394
2562c823 1395bool wxVariantDataArrayString::Eq(wxVariantData& data) const
341287bf 1396{
2562c823 1397 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
341287bf 1398
2562c823 1399 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
341287bf 1400
2562c823 1401 return otherData.m_value == m_value;
341287bf
JS
1402}
1403
2562c823
RR
1404#if wxUSE_STD_IOSTREAM
1405bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
341287bf 1406{
2562c823
RR
1407 // Not implemented
1408 return false;
341287bf 1409}
2562c823 1410#endif
341287bf 1411
2562c823 1412bool wxVariantDataArrayString::Write(wxString& str) const
341287bf 1413{
2562c823
RR
1414 size_t count = m_value.GetCount();
1415 for ( size_t n = 0; n < count; n++ )
341287bf 1416 {
2562c823
RR
1417 if ( n )
1418 str += _T(';');
1419
1420 str += m_value[n];
341287bf 1421 }
341287bf 1422
2562c823 1423 return true;
341287bf
JS
1424}
1425
2562c823
RR
1426
1427#if wxUSE_STD_IOSTREAM
1428bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
341287bf 1429{
2562c823
RR
1430 // Not implemented
1431 return false;
341287bf 1432}
2562c823 1433#endif
341287bf 1434
2562c823
RR
1435
1436bool wxVariantDataArrayString::Read(wxString& str)
341287bf 1437{
2562c823
RR
1438 wxStringTokenizer tk(str, _T(";"));
1439 while ( tk.HasMoreTokens() )
341287bf 1440 {
2562c823 1441 m_value.Add(tk.GetNextToken());
341287bf 1442 }
341287bf 1443
2562c823 1444 return true;
341287bf
JS
1445}
1446
2562c823
RR
1447// wxVariant
1448
1449wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1450{
1451 m_data = new wxVariantDataArrayString(val);
1452 m_name = name;
341287bf
JS
1453}
1454
2562c823 1455bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
341287bf 1456{
2562c823 1457 wxFAIL_MSG( _T("TODO") );
f6bcfd97 1458
2562c823 1459 return false;
341287bf
JS
1460}
1461
2562c823 1462bool wxVariant::operator!=(const wxArrayString& value) const
341287bf 1463{
2562c823 1464 return !(*this == value);
341287bf
JS
1465}
1466
2562c823 1467void wxVariant::operator=(const wxArrayString& value)
341287bf 1468{
2562c823
RR
1469 if (GetType() == wxT("arrstring") &&
1470 m_data->GetRefCount() == 1)
341287bf 1471 {
2562c823 1472 ((wxVariantDataArrayString *)GetData())->SetValue(value);
341287bf
JS
1473 }
1474 else
1475 {
2562c823
RR
1476 UnRef();
1477 m_data = new wxVariantDataArrayString(value);
341287bf
JS
1478 }
1479}
1480
2562c823 1481wxArrayString wxVariant::GetArrayString() const
341287bf 1482{
2562c823
RR
1483 if ( GetType() == wxT("arrstring") )
1484 return ((wxVariantDataArrayString *)GetData())->GetValue();
1485
1486 return wxArrayString();
341287bf
JS
1487}
1488
2562c823
RR
1489// ----------------------------------------------------------------------------
1490// wxVariantDataList
1491// ----------------------------------------------------------------------------
2c3a1064 1492
2562c823 1493class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
341287bf 1494{
2562c823
RR
1495DECLARE_DYNAMIC_CLASS(wxVariantDataList)
1496public:
1497 wxVariantDataList() {}
1498 wxVariantDataList(const wxList& list);
1499 virtual ~wxVariantDataList();
341287bf 1500
2562c823
RR
1501 wxList& GetValue() { return m_value; }
1502 void SetValue(const wxList& value) ;
341287bf 1503
2562c823
RR
1504 virtual bool Eq(wxVariantData& data) const;
1505#if wxUSE_STD_IOSTREAM
1506 virtual bool Write(wxSTD ostream& str) const;
1507#endif
1508 virtual bool Write(wxString& str) const;
1509#if wxUSE_STD_IOSTREAM
1510 virtual bool Read(wxSTD istream& str);
1511#endif
1512 virtual bool Read(wxString& str);
47b378bd 1513 virtual wxString GetType() const { return wxT("list"); }
52e81242 1514
2562c823 1515 void Clear();
341287bf 1516
2562c823
RR
1517protected:
1518 wxList m_value;
1519};
341287bf 1520
2562c823 1521IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
2c3a1064 1522
2562c823 1523wxVariantDataList::wxVariantDataList(const wxList& list)
341287bf 1524{
2562c823 1525 SetValue(list);
341287bf
JS
1526}
1527
2562c823 1528wxVariantDataList::~wxVariantDataList()
341287bf 1529{
2562c823 1530 Clear();
341287bf
JS
1531}
1532
2562c823 1533void wxVariantDataList::SetValue(const wxList& value)
341287bf 1534{
2562c823
RR
1535 Clear();
1536 wxList::compatibility_iterator node = value.GetFirst();
1537 while (node)
341287bf 1538 {
2562c823
RR
1539 wxVariant* var = (wxVariant*) node->GetData();
1540 m_value.Append(new wxVariant(*var));
1541 node = node->GetNext();
341287bf 1542 }
2562c823
RR
1543}
1544
1545void wxVariantDataList::Clear()
1546{
1547 wxList::compatibility_iterator node = m_value.GetFirst();
1548 while (node)
341287bf 1549 {
2562c823
RR
1550 wxVariant* var = (wxVariant*) node->GetData();
1551 delete var;
1552 node = node->GetNext();
341287bf 1553 }
2562c823 1554 m_value.Clear();
341287bf
JS
1555}
1556
2562c823 1557bool wxVariantDataList::Eq(wxVariantData& data) const
a0a302dc 1558{
2562c823
RR
1559 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
1560
1561 wxVariantDataList& listData = (wxVariantDataList&) data;
1562 wxList::compatibility_iterator node1 = m_value.GetFirst();
1563 wxList::compatibility_iterator node2 = listData.GetValue().GetFirst();
1564 while (node1 && node2)
1565 {
1566 wxVariant* var1 = (wxVariant*) node1->GetData();
1567 wxVariant* var2 = (wxVariant*) node2->GetData();
1568 if ((*var1) != (*var2))
1569 return false;
1570 node1 = node1->GetNext();
1571 node2 = node2->GetNext();
1572 }
1573 if (node1 || node2) return false;
1574 return true;
a0a302dc
JS
1575}
1576
2562c823
RR
1577#if wxUSE_STD_IOSTREAM
1578bool wxVariantDataList::Write(wxSTD ostream& str) const
a0a302dc 1579{
2562c823
RR
1580 wxString s;
1581 Write(s);
1582 str << (const char*) s.mb_str();
1583 return true;
a0a302dc 1584}
2562c823 1585#endif
a0a302dc 1586
2562c823 1587bool wxVariantDataList::Write(wxString& str) const
a0a302dc 1588{
2562c823
RR
1589 str = wxEmptyString;
1590 wxList::compatibility_iterator node = m_value.GetFirst();
1591 while (node)
a0a302dc 1592 {
2562c823
RR
1593 wxVariant* var = (wxVariant*) node->GetData();
1594 if (node != m_value.GetFirst())
1595 str += wxT(" ");
1596 wxString str1;
1597 str += var->MakeString();
1598 node = node->GetNext();
a0a302dc 1599 }
2562c823
RR
1600
1601 return true;
a0a302dc 1602}
2f620946 1603
2562c823
RR
1604#if wxUSE_STD_IOSTREAM
1605bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
2f620946 1606{
2562c823
RR
1607 wxFAIL_MSG(wxT("Unimplemented"));
1608 // TODO
1609 return false;
2f620946 1610}
2562c823 1611#endif
2f620946 1612
2562c823 1613bool wxVariantDataList::Read(wxString& WXUNUSED(str))
2f620946 1614{
2562c823
RR
1615 wxFAIL_MSG(wxT("Unimplemented"));
1616 // TODO
1617 return false;
2f620946
RR
1618}
1619
2562c823
RR
1620// wxVariant
1621
1622wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
2f620946 1623{
2562c823
RR
1624 m_data = new wxVariantDataList(val);
1625 m_name = name;
2f620946 1626}
341287bf 1627
2562c823 1628bool wxVariant::operator== (const wxList& value) const
edca7a82 1629{
2562c823 1630 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
edca7a82 1631
2562c823
RR
1632 wxVariantDataList other(value);
1633 return (GetData()->Eq(other));
edca7a82
GT
1634}
1635
2562c823 1636bool wxVariant::operator!= (const wxList& value) const
edca7a82
GT
1637{
1638 return (!((*this) == value));
1639}
1640
2562c823 1641void wxVariant::operator= (const wxList& value)
edca7a82 1642{
2562c823
RR
1643 if (GetType() == wxT("list") &&
1644 m_data->GetRefCount() == 1)
edca7a82 1645 {
2562c823 1646 ((wxVariantDataList*)GetData())->SetValue(value);
edca7a82
GT
1647 }
1648 else
1649 {
2562c823
RR
1650 UnRef();
1651 m_data = new wxVariantDataList(value);
edca7a82
GT
1652 }
1653}
1654
2562c823 1655wxList& wxVariant::GetList() const
edca7a82 1656{
2562c823 1657 wxASSERT( (GetType() == wxT("list")) );
edca7a82 1658
2562c823
RR
1659 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1660}
edca7a82 1661
2562c823
RR
1662// Make empty list
1663void wxVariant::NullList()
edca7a82 1664{
2562c823 1665 SetData(new wxVariantDataList());
edca7a82
GT
1666}
1667
2562c823
RR
1668// Append to list
1669void wxVariant::Append(const wxVariant& value)
edca7a82 1670{
2562c823
RR
1671 wxList& list = GetList();
1672
1673 list.Append(new wxVariant(value));
edca7a82
GT
1674}
1675
2562c823
RR
1676// Insert at front of list
1677void wxVariant::Insert(const wxVariant& value)
1678{
1679 wxList& list = GetList();
fb42d7c3 1680
2562c823
RR
1681 list.Insert(new wxVariant(value));
1682}
1683
1684// Returns true if the variant is a member of the list
1685bool wxVariant::Member(const wxVariant& value) const
fb42d7c3 1686{
2562c823 1687 wxList& list = GetList();
fb42d7c3 1688
2562c823
RR
1689 wxList::compatibility_iterator node = list.GetFirst();
1690 while (node)
1691 {
1692 wxVariant* other = (wxVariant*) node->GetData();
1693 if (value == *other)
1694 return true;
1695 node = node->GetNext();
1696 }
cab1a605 1697 return false;
fb42d7c3
VZ
1698}
1699
2562c823
RR
1700// Deletes the nth element of the list
1701bool wxVariant::Delete(size_t item)
fb42d7c3 1702{
2562c823
RR
1703 wxList& list = GetList();
1704
1705 wxASSERT_MSG( (item < list.GetCount()), wxT("Invalid index to Delete") );
1706 wxList::compatibility_iterator node = list.Item(item);
1707 wxVariant* variant = (wxVariant*) node->GetData();
1708 delete variant;
1709 list.Erase(node);
1710 return true;
fb42d7c3
VZ
1711}
1712
2562c823
RR
1713// Clear list
1714void wxVariant::ClearList()
fb42d7c3 1715{
2562c823 1716 if (!IsNull() && (GetType() == wxT("list")))
fb42d7c3 1717 {
2562c823 1718 ((wxVariantDataList*) m_data)->Clear();
fb42d7c3
VZ
1719 }
1720 else
1721 {
2562c823
RR
1722 if (!GetType().IsSameAs(wxT("list")))
1723 UnRef();
fb42d7c3 1724
2562c823
RR
1725 m_data = new wxVariantDataList;
1726 }
fb42d7c3
VZ
1727}
1728
60acae80
RR
1729// Treat a list variant as an array
1730wxVariant wxVariant::operator[] (size_t idx) const
1731{
60acae80 1732 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
60acae80
RR
1733
1734 if (GetType() == wxT("list"))
1735 {
1736 wxVariantDataList* data = (wxVariantDataList*) m_data;
1737 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1738 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1739 }
60acae80
RR
1740 return wxNullVariant;
1741}
1742
1743wxVariant& wxVariant::operator[] (size_t idx)
1744{
1745 // We can't return a reference to a variant for a string list, since the string
1746 // is actually stored as a char*, not a variant.
1747
1748 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1749
1750 wxVariantDataList* data = (wxVariantDataList*) m_data;
1751 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
1752
1753 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1754}
1755
1756// Return the number of elements in a list
1757size_t wxVariant::GetCount() const
1758{
60acae80 1759 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
60acae80
RR
1760
1761 if (GetType() == wxT("list"))
1762 {
1763 wxVariantDataList* data = (wxVariantDataList*) m_data;
1764 return data->GetValue().GetCount();
1765 }
60acae80
RR
1766 return 0;
1767}
1768
2562c823 1769// ----------------------------------------------------------------------------
341287bf 1770// Type conversion
2562c823
RR
1771// ----------------------------------------------------------------------------
1772
341287bf
JS
1773bool wxVariant::Convert(long* value) const
1774{
1775 wxString type(GetType());
223d09f6 1776 if (type == wxT("double"))
2562c823 1777 *value = (long) (((wxVariantDoubleData*)GetData())->GetValue());
223d09f6 1778 else if (type == wxT("long"))
341287bf 1779 *value = ((wxVariantDataLong*)GetData())->GetValue();
862416e0 1780#ifdef HAVE_BOOL
223d09f6 1781 else if (type == wxT("bool"))
341287bf 1782 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1783#endif
223d09f6 1784 else if (type == wxT("string"))
52de37c7 1785 *value = wxAtol(((wxVariantDataString*)GetData())->GetValue());
341287bf 1786 else
cab1a605 1787 return false;
341287bf 1788
cab1a605 1789 return true;
341287bf
JS
1790}
1791
1792bool wxVariant::Convert(bool* value) const
1793{
1794 wxString type(GetType());
223d09f6 1795 if (type == wxT("double"))
2562c823 1796 *value = ((int) (((wxVariantDoubleData*)GetData())->GetValue()) != 0);
223d09f6 1797 else if (type == wxT("long"))
341287bf 1798 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
862416e0 1799#ifdef HAVE_BOOL
223d09f6 1800 else if (type == wxT("bool"))
341287bf 1801 *value = ((wxVariantDataBool*)GetData())->GetValue();
862416e0 1802#endif
223d09f6 1803 else if (type == wxT("string"))
341287bf
JS
1804 {
1805 wxString val(((wxVariantDataString*)GetData())->GetValue());
1806 val.MakeLower();
b1638abf 1807 if (val == wxT("true") || val == wxT("yes") || val == wxT('1') )
cab1a605 1808 *value = true;
b1638abf 1809 else if (val == wxT("false") || val == wxT("no") || val == wxT('0') )
cab1a605 1810 *value = false;
341287bf 1811 else
cab1a605 1812 return false;
341287bf
JS
1813 }
1814 else
cab1a605 1815 return false;
341287bf 1816
cab1a605 1817 return true;
341287bf
JS
1818}
1819
1820bool wxVariant::Convert(double* value) const
1821{
1822 wxString type(GetType());
223d09f6 1823 if (type == wxT("double"))
2562c823 1824 *value = ((wxVariantDoubleData*)GetData())->GetValue();
223d09f6 1825 else if (type == wxT("long"))
341287bf 1826 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
862416e0 1827#ifdef HAVE_BOOL
223d09f6 1828 else if (type == wxT("bool"))
341287bf 1829 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1830#endif
223d09f6 1831 else if (type == wxT("string"))
52de37c7 1832 *value = (double) wxAtof(((wxVariantDataString*)GetData())->GetValue());
341287bf 1833 else
cab1a605 1834 return false;
341287bf 1835
cab1a605 1836 return true;
341287bf
JS
1837}
1838
af717fa8 1839bool wxVariant::Convert(wxUniChar* value) const
341287bf
JS
1840{
1841 wxString type(GetType());
223d09f6 1842 if (type == wxT("char"))
341287bf 1843 *value = ((wxVariantDataChar*)GetData())->GetValue();
223d09f6 1844 else if (type == wxT("long"))
341287bf 1845 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
862416e0 1846#ifdef HAVE_BOOL
223d09f6 1847 else if (type == wxT("bool"))
341287bf 1848 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1849#endif
341287bf 1850 else
cab1a605 1851 return false;
341287bf 1852
cab1a605 1853 return true;
341287bf
JS
1854}
1855
af717fa8
VS
1856bool wxVariant::Convert(char* value) const
1857{
1858 wxUniChar ch;
1859 if ( !Convert(&ch) )
1860 return false;
1861 *value = ch;
1862 return true;
1863}
1864
1865bool wxVariant::Convert(wchar_t* value) const
1866{
1867 wxUniChar ch;
1868 if ( !Convert(&ch) )
1869 return false;
1870 *value = ch;
1871 return true;
1872}
1873
341287bf
JS
1874bool wxVariant::Convert(wxString* value) const
1875{
1876 *value = MakeString();
cab1a605 1877 return true;
341287bf
JS
1878}
1879
e2b87f38 1880#if wxUSE_DATETIME
edca7a82
GT
1881bool wxVariant::Convert(wxDateTime* value) const
1882{
1883 wxString type(GetType());
1884 if (type == wxT("datetime"))
9708db20 1885 {
edca7a82 1886 *value = ((wxVariantDataDateTime*)GetData())->GetValue();
cab1a605 1887 return true;
dc259b79 1888 }
9708db20
JS
1889 // Fallback to string conversion
1890 wxString val;
9a8a9e99 1891 return Convert(&val) &&
52de37c7
VS
1892 (value->ParseDateTime(val.c_str()/*FIXME-UTF8*/) ||
1893 value->ParseDate(val.c_str()/*FIXME-UTF8*/) ||
1894 value->ParseTime(val.c_str()/*FIXME-UTF8*/));
edca7a82 1895}
b1e343f2 1896#endif // wxUSE_DATETIME
d5dc103f
VZ
1897
1898#endif // wxUSE_VARIANT