-
Notifications
You must be signed in to change notification settings - Fork 91
/
jsonval.cpp
3598 lines (3171 loc) · 101 KB
/
jsonval.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/////////////////////////////////////////////////////////////////////////////
// Name: jsonval.cpp
// Purpose: the wxJSON class that holds a JSON value
// Author: Luciano Cattani
// Created: 2007/10/01
// RCS-ID: $Id: jsonval.cpp,v 1.12 2008/03/06 10:25:18 luccat Exp $
// Copyright: (c) 2007 Luciano Cattani
// Licence: wxWidgets licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "jsonval.cpp"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include <wx/log.h>
#include <wx/debug.h>
#include <wx/arrimpl.cpp>
#include "jsonval.h"
WX_DEFINE_OBJARRAY( wxJSONInternalArray );
// the trace mask used in wxLogTrace() function
// static const wxChar* traceMask = _T("jsonval");
static const wxChar* traceMask = _T("jsonval");
static const wxChar* compareTraceMask = _T("sameas");
static const wxChar* cowTraceMask = _T("traceCOW" );
/*******************************************************************
class wxJSONRefData
*******************************************************************/
/*! \class wxJSONRefData
\brief The reference counted JSON value data (internal use).
Starting from version 0.4, the JSON value class use the reference
counting tecnique (also know as \e copy-on-write) described in the
\b wxWidgets documentation in order to speed up processing.
The class is used internally by the wxJSONValue class which does
all processing.
To know more about COW see \ref json_internals_cow
*/
#if defined( WXJSON_USE_VALUE_COUNTER )
// The progressive counter (used for debugging only)
int wxJSONRefData::sm_progr = 1;
#endif
//! Constructor.
wxJSONRefData::wxJSONRefData()
{
m_lineNo = -1;
m_refCount = 1;
m_memBuff = 0;
#if defined( WXJSON_USE_VALUE_COUNTER )
m_progr = sm_progr;
++sm_progr;
wxLogTrace( traceMask, _T("(%s) JSON refData ctor progr=%d"),
__PRETTY_FUNCTION__, m_progr);
#endif
}
// Dtor
wxJSONRefData::~wxJSONRefData()
{
if ( m_memBuff ) {
delete m_memBuff;
}
}
// Return the number of objects that reference this data.
int
wxJSONRefData::GetRefCount() const
{
return m_refCount;
}
/*******************************************************************
class wxJSONValue
*******************************************************************/
/*! \class wxJSONValue
\brief The JSON value class implementation.
This class holds a JSON value which may be of variuos types (see the
wxJSONType constants for a description of the types).
To know more about the internal representation of JSON values see
\ref pg_json_internals.
Starting from version 0.5 the wxJSON library supports 64-bits integers on
platforms that have native support for very large integers.
Note that the integer type is still stored as a generic wxJSONTYPE_(U)INT
constant regardless the size of the value but the JSON value class defines
functions in order to let the user know if an integer value fits in 16, 32
or 64 bit integer.
To know more about 64-bits integer support see \ref json_internals_integer
Storing values in a JSON value object of this class is very simple.
The following is an example:
\code
wxJSONValue v( _T( "A string")); // store a string value in the object
wxString s = v.AsString(); // get the string value
v = 12; // now 'v' contains an integer value
int i = v.AsInt(); // get the integer
\endcode
\par The C-string JSON value object
The wxJSONValue(const wxChar*) ctor allows you to create a JSON value
object that contains a string value which is stored as a
\e pointer-to-static-string.
Beware that this ctor DOES NOT copy the string: it only stores the
pointer in a data member and the pointed-to buffer is not deleted
by the dtor.
If the string is not static you have to use the wxJSONValue(const wxString&)
constructor.
Also note that this does NOT mean that the value stored in this JSON
object cannot change: you can assign whatever other value you want,
an integer, a double or an array of values.
What I intended is that the pointed-to string must exist for the lifetime
of the wxJSONValue object.
The following code is perfectly legal:
\code
wxJSONvalue aString( "this is a static string" );
aString = 10;
\endcode
To know more about this topic see \ref json_internals_cstring.
Starting from version 1.3 the class can hold binary memory buffers
as an extension to the JSON syntax. Memory buffers are stored as
\b wxMemoryBuffer objects which contain binary data. The class
uses reference counting for the copy and assignment operation but
it is not a \e copy-on-write structure.
To know more about memory buffers read \ref wxjson_tutorial_memorybuff
\sa the \ref wxjson_tutorial.
*/
#if defined( WXJSON_USE_VALUE_COUNTER )
// The progressive counter (used for debugging only)
int wxJSONValue::sm_progr = 1;
#endif
//! Constructors.
/*!
The overloaded constructors allow the user to construct a JSON value
object that holds the specified value and type of value.
The default ctor construct a valid JSON object that constains a \b null
value.
If you want to create an \b invalid JSON value object you have to use the
\c wxJSONValue( wxJSONTYPE_INVALID ) ctor.
Note that this object is not a valid JSON value - to know more about this
topic see the SetType() function.
To create an empty array or key/value map use the following:
\code
wxJSONvalue v1( wxJSONTYPE_ARRAY );
wxJSONvalue v2( wxJSONTYPE_OBJECT );
\endcode
*/
wxJSONValue::wxJSONValue()
{
m_refData = 0;
Init( wxJSONTYPE_NULL );
}
//! Initialize the JSON value class.
/*!
The function is called by the ctors and allocates a new instance of
the wxJSONRefData class and sets the type of the JSON value.
Note that only the type is set, not the value.
Also note that this function may be called from other memberfunctions
if the \c m_refData data member is NULL.
*/
wxJSONRefData*
wxJSONValue::Init( wxJSONType type )
{
wxJSONRefData* data = GetRefData();
if ( data != 0 ) {
UnRef();
}
// we allocate a new instance of the referenced data
data = new wxJSONRefData();
wxJSON_ASSERT( data );
// in release builds we do not have ASSERT so we check 'data' before
// using it
if ( data ) {
data->m_type = type;
data->m_commentPos = wxJSONVALUE_COMMENT_BEFORE;
}
SetRefData( data );
#if defined( WXJSON_USE_VALUE_COUNTER )
m_progr = sm_progr;
++sm_progr;
wxLogTrace( cowTraceMask, _T("(%s) Init a new object progr=%d"),
__PRETTY_FUNCTION__, m_progr );
#endif
return data;
}
//! \overload wxJSONValue()
wxJSONValue::wxJSONValue( wxJSONType type )
{
m_refData = 0;
Init( type );
}
//! \overload wxJSONValue()
wxJSONValue::wxJSONValue( int i )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_INT );
wxJSON_ASSERT( data );
if ( data != 0 ) {
// the 'VAL_INT' macro expands to 'm_valLong' or 'm_valInt64' depending
// on 64-bits integer support being enabled on not
data->m_value.VAL_INT = i;
}
}
//! \overload wxJSONValue()
wxJSONValue::wxJSONValue( unsigned int ui )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_UINT );
wxJSON_ASSERT( data );
if ( data != 0 ) {
// the 'VAL_UINT' macro expands to 'm_valULong' or 'm_valUInt64' depending
// on 64-bits integer support being enabled on not
data->m_value.VAL_UINT = ui;
}
}
//! \overload wxJSONValue()
wxJSONValue::wxJSONValue( short int i )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_INT );
wxJSON_ASSERT( data );
if ( data != 0 ) {
// the 'VAL_INT' macro expands to 'm_valLong' or 'm_valInt64' depending
// on 64-bits integer support being enabled on not
data->m_value.VAL_INT = i;
}
}
//! \overload wxJSONValue()
wxJSONValue::wxJSONValue( unsigned short ui )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_UINT );
wxJSON_ASSERT( data );
if ( data != 0 ) {
// the 'VAL_UINT' macro expands to 'm_valULong' or 'm_valUInt64' depending
// on 64-bits integer support being enabled on not
data->m_value.VAL_UINT = ui;
}
}
//! \overload wxJSONValue()
wxJSONValue::wxJSONValue( bool b )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_BOOL );
wxJSON_ASSERT( data );
if ( data != 0 ) {
data->m_value.m_valBool = b;
}
}
//! \overload wxJSONValue()
wxJSONValue::wxJSONValue( double d )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_DOUBLE );
wxJSON_ASSERT( data );
if ( data != 0 ) {
data->m_value.m_valDouble = d;
}
}
//! \overload wxJSONValue()
wxJSONValue::wxJSONValue( const wxChar* str )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_CSTRING );
wxJSON_ASSERT( data );
if ( data != 0 ) {
#if !defined( WXJSON_USE_CSTRING )
data->m_type = wxJSONTYPE_STRING;
data->m_valString.assign( str );
#else
data->m_value.m_valCString = str;
#endif
}
}
//! \overload wxJSONValue()
wxJSONValue::wxJSONValue( const wxString& str )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_STRING );
wxJSON_ASSERT( data );
if ( data != 0 ) {
data->m_valString.assign( str );
}
}
//! \overload wxJSONValue()
wxJSONValue::wxJSONValue( long int l )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_INT );
wxJSON_ASSERT( data );
if ( data != 0 ) {
data->m_value.VAL_INT = l;
}
}
//! \overload wxJSONValue()
wxJSONValue::wxJSONValue( unsigned long int ul )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_UINT );
wxJSON_ASSERT( data );
if ( data != 0 ) {
data->m_value.VAL_UINT = ul;
}
}
//! Construct a JSON value object of type \e memory \e buffer
/*!
Note that this ctor makes a deep copy of \c buff so changes made
to the original buffer does not reflect to the buffer stored in this
JSON value.
*/
wxJSONValue::wxJSONValue( const wxMemoryBuffer& buff )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_MEMORYBUFF );
wxJSON_ASSERT( data );
if ( data != 0 ) {
data->m_memBuff = new wxMemoryBuffer();
const void* ptr = buff.GetData();
size_t buffLen = buff.GetDataLen();
if ( buffLen > 0 ) {
data->m_memBuff->AppendData( ptr, buffLen );
}
}
}
//! Construct a JSON value object of type \e memory \e buffer
/*!
Note that this ctor makes a deep copy of \c buff so changes made
to the original buffer does not reflect to the buffer stored in this
JSON value.
*/
wxJSONValue::wxJSONValue( const void* buff, size_t len )
{
m_refData = 0;
wxJSONRefData* data = Init( wxJSONTYPE_MEMORYBUFF );
wxJSON_ASSERT( data );
if ( data != 0 && len > 0 ) {
data->m_memBuff = new wxMemoryBuffer();
data->m_memBuff->AppendData( buff, len );
}
}
//! Copy constructor
/*!
The function copies the content of \c other in this
object.
Note that the JSON value object is not really copied;
the function calls Ref() in order to increment
the reference count of the \c wxJSONRefData structure.
*/
wxJSONValue::wxJSONValue( const wxJSONValue& other )
{
m_refData = 0;
Ref( other );
// the progressive counter of the ctor is not copied from
// the other wxJSONValue object: only data is shared, the
// progressive counter is not shared because this object
// is a copy of 'other' and it has its own progressive
#if defined( WXJSON_USE_VALUE_COUNTER )
m_progr = sm_progr;
++sm_progr;
wxLogTrace( cowTraceMask, _T("(%s) Copy ctor - progr=%d other progr=%d"),
__PRETTY_FUNCTION__, m_progr, other.m_progr );
#endif
}
//! Dtor - calls UnRef().
wxJSONValue::~wxJSONValue()
{
UnRef();
}
// functions for retreiving the value type: they are all 'const'
//! Return the type of the value stored in the object.
/*!
This function is the only one that does not ASSERT that the
\c m_refData data member is not NULL.
In fact, if the JSON value object does not contain a pointer
to a wxJSONRefData structure, the function returns the
wxJSONTYPE_INVALID constant which represent an invalid JSON value object.
Also note that the pointer to the referenced data structure
should NEVER be NULL.
\par Integer types
Integers are stored internally in a \b signed/unsigned \b long \b int
or, on platforms that support 64-bits integers, in a
\b wx(U)Int64 data type.
When constructed, it is assigned a generic integer type that only
depends on the sign: wxJSON_(U)INT regardless the size of the
stored value.
This function can be used to know the actual size requirement
of the stored value and how it can be retrieved. The value
returned by this function is:
- for signed integers:
- \b wxJSONTYPE_SHORT if the value is between SHORT_MIN and SHORT_MAX
- \b wxJSONTYPE_LONG if the value is between LONG_MIN and LONG_MAX
and greater than SHORT_MAX and less than SHORT_MIN
- \b wxJSONTYPE_INT64 if the value is greater than LONG_MAX and
less than LONG_MIN
- for unsigned integers:
- \b wxJSONTYPE_USHORT if the value is between 0 and USHORT_MAX
- \b wxJSONTYPE_ULONG if the value is between 0 and ULONG_MAX
and greater than USHORT_MAX
- \b wxJSONTYPE_UINT64 if the value is greater than ULONG_MAX
Note that this function never returns the wxJSONTYPE_(U)INT constant
because the \b int data type may have the same width as SHORT or LONG
depending on the platform.
This does not mean that you cannot use \b int as the return value: if
you use \b wxWidgets to develop application in only one platform, you
can use \b int because you know the size of the data type.
Otherwise, if is preferable to always use \b long instead of \b int.
Also note that the class defines the \c IsInt() memberfunction which
works fine regardless the actual width of the \b int data type.
This function returns TRUE if the stored value fits in a \b int data
type whatever its size is on the current platform (16 or 32-bits).
\sa SetType IsInt
*/
wxJSONType
wxJSONValue::GetType() const
{
wxJSONRefData* data = GetRefData();
wxJSONType type = wxJSONTYPE_INVALID;
if ( data ) {
type = data->m_type;
// for integers and unsigned ints check the storage requirements
// note that ints are stored as 'long' or as 'long long'
switch ( type ) {
case wxJSONTYPE_INT :
// check if the integer fits in a SHORT INT
if ( data->m_value.VAL_INT >= SHORT_MIN &&
data->m_value.VAL_INT <= SHORT_MAX ) {
type = wxJSONTYPE_SHORT;
}
// check if the value fits in LONG INT
else if ( data->m_value.VAL_INT >= LONG_MIN
&& data->m_value.VAL_INT <= LONG_MAX ) {
type = wxJSONTYPE_LONG;
}
else {
type = wxJSONTYPE_INT64;
}
break;
case wxJSONTYPE_UINT :
if ( data->m_value.VAL_UINT <= USHORT_MAX ) {
type = wxJSONTYPE_USHORT;
}
else if ( data->m_value.VAL_UINT <= ULONG_MAX ) {
type = wxJSONTYPE_ULONG;
}
else {
type = wxJSONTYPE_UINT64;
}
break;
default :
break;
}
}
return type;
}
//! Return TRUE if the type of the value is wxJSONTYPE_NULL.
bool
wxJSONValue::IsNull() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_NULL ) {
r = true;
}
return r;
}
//! Return TRUE if the value stored is valid
/*!
The function returns TRUE if the wxJSONValue object was correctly
initialized - that is it contains a valid value.
A JSON object is valid if its type is not equal to wxJSONTYPE_INVALID.
Please note that the default ctor of wxJSONValue constructs a \b valid
JSON object of type \b null.
To create an invalid object you have to use;
\code
wxJSONValue v( wxJSONTYPE_INVALID );
\endcode
*/
bool
wxJSONValue::IsValid() const
{
wxJSONType type = GetType();
bool r = false;
if ( type != wxJSONTYPE_INVALID ) {
r = true;
}
return r;
}
//! Return TRUE if the type of the value stored is integer.
/*!
This function returns TRUE if the stored value is of
type signed integer and the numeric value fits in a
\b int data type.
In other words, the function returns TRUE if the \c wxJSONRefData::m_type
data member is of type \c wxJSONTYPE_INT and:
\code
INT_MIN <= m_value <= INT_MAX
\endcode
Note that if you are developing cross-platform applications you should never
use \b int as the integer data type but \b long for 32-bits integers and
\b short for 16-bits integers.
This is because the \b int data type may have different width on different
platforms.
Regardless the widht of the data type (16 or 32 bits), the function returns
the correct result because it relies on the INT_MAX and INT_MIN macros.
\sa \ref json_internals_integer
*/
bool
wxJSONValue::IsInt() const
{
wxJSONType type = GetType();
bool r = false;
// if the type is SHORT the value fits into an INT, too
if ( type == wxJSONTYPE_SHORT ) {
r = true;
}
else if ( type == wxJSONTYPE_LONG ) {
// in case of LONG, check if the bit width is the same
if ( INT_MAX == LONG_MAX ) {
r = true;
}
}
return r;
}
//! Return TRUE if the type of the value stored is 16-bit integer.
/*!
This function returns TRUE if the stored value is of
type signed integer and the numeric value fits in a
\b short \b int data type (16-bit integer).
In other words, the function returns TRUE if the \c wxJSONRefData::m_type
data member is of type \c wxJSONTYPE_INT and:
\code
SHORT_MIN <= m_value <= SHORT_MAX
\endcode
\sa \ref json_internals_integer
*/
bool
wxJSONValue::IsShort() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_SHORT ) {
r = true;
}
return r;
}
//! Return TRUE if the type of the value stored is a unsigned int.
/*!
This function returns TRUE if the stored value is of
type unsigned integer and the numeric value fits int a
\b int data type.
In other words, the function returns TRUE if the \c wxJSONRefData::m_type
data member is of type \c wxJSONTYPE_UINT and:
\code
0 <= m_value <= UINT_MAX
\endcode
Note that if you are developing cross-platform applications you should never
use \b unsigned \b int as the integer data type but \b unsigned \b long for
32-bits integers and \b unsigned \b short for 16-bits integers.
This is because the \b unsigned \b int data type may have different width
on different platforms.
Regardless the widht of the data type (16 or 32 bits), the function returns
the correct result because it relies on the UINT_MAX macro.
\sa \ref json_internals_integer
*/
bool
wxJSONValue::IsUInt() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_USHORT ) {
r = true;
}
else if ( type == wxJSONTYPE_ULONG ) {
if ( INT_MAX == LONG_MAX ) {
r = true;
}
}
return r;
}
//! Return TRUE if the type of the value stored is a unsigned short.
/*!
This function returns TRUE if the stored value is of
type unsigned integer and the numeric value fits in a
\b unsigned \b short \b int data type.
In other words, the function returns TRUE if the \c wxJSONRefData::m_type
data member is of type \c wxJSONTYPE_UINT and:
\code
0 <= m_value <= USHORT_MAX
\endcode
\sa \ref json_internals_integer
*/
bool
wxJSONValue::IsUShort() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_USHORT ) {
r = true;
}
return r;
}
//! Return TRUE if the stored value is an integer which fits in a long int
/*!
This function returns TRUE if the stored value is of
type signed LONG integer and the numeric value fits int a
\b long \b int data type.
In other words, the function returns TRUE if the \c wxJSONRefData::m_type
data member is of type \c wxJSONTYPE_INT and:
\code
LONG_MIN <= m_value <= LONG_MAX
\endcode
\sa \ref json_internals_integer
*/
bool
wxJSONValue::IsLong() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_LONG || type == wxJSONTYPE_SHORT ) {
r = true;
}
return r;
}
//! Return TRUE if the stored value is an integer which fits in a unsigned long int
/*!
This function returns TRUE if the stored value is of
type unsigned LONG integer and the numeric value fits int a
\b unsigned \b long \b int data type.
In other words, the function returns TRUE if the \c wxJSONRefData::m_type
data member is of type \c wxJSONTYPE_UINT and:
\code
0 <= m_value <= ULONG_MAX
\endcode
\sa \ref json_internals_integer
*/
bool
wxJSONValue::IsULong() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_ULONG || type == wxJSONTYPE_USHORT ) {
r = true;
}
return r;
}
//! Return TRUE if the type of the value stored is a boolean.
bool
wxJSONValue::IsBool() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_BOOL ) {
r = true;
}
return r;
}
//! Return TRUE if the type of the value stored is a double.
bool
wxJSONValue::IsDouble() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_DOUBLE ) {
r = true;
}
return r;
}
//! Return TRUE if the type of the value stored is a wxString object.
bool
wxJSONValue::IsString() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_STRING ) {
r = true;
}
return r;
}
//! Return TRUE if the type of the value stored is a pointer to a static C string.
/*!
This function returns TRUE if, and only if the stored value is a
pointer to a static C-string and the C-string storage is enabled in
the wxJSON library.
By default, C-string storage is not enabled in the library so this
function always returns FALSE.
To know more about C-strings read \ref json_internals_cstring
*/
bool
wxJSONValue::IsCString() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_CSTRING ) {
r = true;
}
return r;
}
//! Return TRUE if the type of the value stored is an array type.
bool
wxJSONValue::IsArray() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_ARRAY ) {
r = true;
}
return r;
}
//! Return TRUE if the type of this value is a key/value map.
bool
wxJSONValue::IsObject() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_OBJECT ) {
r = true;
}
return r;
}
//! Return TRUE if the type of this value is a binary memory buffer.
bool
wxJSONValue::IsMemoryBuff() const
{
wxJSONType type = GetType();
bool r = false;
if ( type == wxJSONTYPE_MEMORYBUFF ) {
r = true;
}
return r;
}
// get the stored value; all these functions are 'const'
//! Return the stored value as an integer.
/*!
The function returns the stored value as an integer.
Note that the function does not check that the type of the
value is actually an integer and it just returns the content
of the wxJSONValueHolder union.
However, in debug builds, the function ASSERTs that the
type of the stored value \c IsInt().
\sa \ref json_internals_integer
\sa \ref wxjson_tutorial_get
*/
int
wxJSONValue::AsInt() const
{
wxJSONRefData* data = GetRefData();
wxJSON_ASSERT( data );
int i = (int) data->m_value.VAL_INT;
wxJSON_ASSERT( IsInt());
return i;
}
//! Return the stored value as a boolean.
/*!
The function returns the stored value as a boolean.
Note that the function does not check that the type of the
value is actually a boolean and it just returns the content
of the wxJSONValueHolder union.
However, in debug builds, the function ASSERTs that the
type of the stored value is wxJSONTYPE_BOOL.
\sa \ref wxjson_tutorial_get
*/
bool
wxJSONValue::AsBool() const
{
wxJSONRefData* data = GetRefData();
wxJSON_ASSERT( data );
wxJSON_ASSERT( data->m_type == wxJSONTYPE_BOOL );
return data->m_value.m_valBool;
}
//! Return the stored value as a double.
/*!
The function returns the stored value as a double.
Note that the function does not check that the type of the
value is actually a double and it just returns the content
of the wxJSONValueHolder union as if it was a double.
However, in debug builds, the function ASSERTs that the
type of the stored value \c IsDouble().
\sa \ref wxjson_tutorial_get
*/
double
wxJSONValue::AsDouble() const
{
wxJSONRefData* data = GetRefData();
wxJSON_ASSERT( data );
double d = data->m_value.m_valDouble;
wxJSON_ASSERT( IsDouble());
return d;
}
//! Return the stored value as a wxWidget's string.
/*!
The function returns a string representation of the value
stored in the JSON object.
All value types are converted to a string by this function
and returned as a string:
\li For integer the string is the string representation of
the numerical value in decimal notation; the function uses the
\b wxString::Printf() function for the conversion
\li for doubles, the value is converted to a string using the
\b wxString::Printf("%.10g") function; the format string specifies
a precision of ten decimal digits and suppress trailing ZEROes
\li for booleans the string returned is: \b true or \b false.
\li if the value is a NULL value the \b null literal string is returned.
\li if the value is of type wxJSONTYPE_INVALID, the literal string \b <invalid>
is returned. Note that this is NOT a valid JSON text.
\li if the value is of type wxJSONTYPE_MEMORYBUFF the string returned contains the
hexadecimal digits of the first 5 bytes preceeded by the length of the buffer,
enclosed in parenthesis
If the value is an array or map, the returned string is the number of
elements is the array/object enclosed in the JSON special characters that
identifies the array/object. Example:
\code
[0] // an empty array
{12} // an object of 12 elements
\endcode
\sa \ref wxjson_tutorial_get
*/
wxString
wxJSONValue::AsString() const
{
wxJSONRefData* data = GetRefData();
wxJSON_ASSERT( data );
wxString s;
int size = Size();
switch ( data->m_type ) {
case wxJSONTYPE_STRING :
s.assign( data->m_valString);
break;
case wxJSONTYPE_CSTRING :
s.assign( data->m_value.m_valCString);
break;
case wxJSONTYPE_INT :
#if defined( wxJSON_64BIT_INT )
s.Printf( _T("%") wxLongLongFmtSpec _T("i"),
data->m_value.m_valInt64 );
#else
s.Printf( _T("%ld"), data->m_value.m_valLong );
#endif
break;
case wxJSONTYPE_UINT :
#if defined( wxJSON_64BIT_INT )
s.Printf( _T("%") wxLongLongFmtSpec _T("u"),
data->m_value.m_valUInt64 );
#else
s.Printf( _T("%lu"), data->m_value.m_valULong );
#endif
break;
case wxJSONTYPE_DOUBLE :
s.Printf( _T("%.10g"), data->m_value.m_valDouble );
break;
case wxJSONTYPE_BOOL :
s.assign( ( data->m_value.m_valBool ?
_T("true") : _T("false") ));
break;
case wxJSONTYPE_NULL :
s.assign( _T( "null"));
break;
case wxJSONTYPE_INVALID :
s.assign( _T( "<invalid>"));
break;
case wxJSONTYPE_ARRAY :
s.Printf( _T("[%d]"), size );
break;
case wxJSONTYPE_OBJECT :
s.Printf( _T("{%d}"), size );
break;
case wxJSONTYPE_MEMORYBUFF :
s = MemoryBuffToString( *(data->m_memBuff), 5 );
break;