Coverage Report

Created: 2025-07-23 07:02

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