1 /////////////////////////////////////////////////////////////////////////////
2 // Name: jsonval.cpp
3 // Purpose: the wxJSON class that holds a JSON value
4 // Author: Luciano Cattani
5 // Created: 2007/10/01
6 // RCS-ID: $Id: jsonval.cpp,v 1.12 2008/03/06 10:25:18 luccat Exp $
7 // Copyright: (c) 2007 Luciano Cattani
8 // Licence: wxWidgets licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 //#ifdef __GNUG__
12 // #pragma implementation "jsonval.cpp"
13 //#endif
14
15 // make wxLogTrace a noop, it's really slow
16 // must be defined before including debug.h
17 #define wxDEBUG_LEVEL 0
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26
27 #include <wx/log.h>
28 #include <wx/arrimpl.cpp>
29
30 #include <wx/jsonval.h>
31
32
33 WX_DEFINE_OBJARRAY( wxJSONInternalArray );
34
35 #if wxCHECK_VERSION(3, 0, 0)
36 #define compatibleLongLongFmtSpec _T(wxLongLongFmtSpec)
37 #else
38 #define compatibleLongLongFmtSpec wxLongLongFmtSpec
39 #endif
40
41 #if wxDEBUG_LEVEL > 0
42 // the trace mask used in wxLogTrace() function
43 // static const wxChar* traceMask = _T("jsonval");
44 static const wxChar* traceMask = _T("jsonval");
45 static const wxChar* compareTraceMask = _T("sameas");
46 static const wxChar* cowTraceMask = _T("traceCOW" );
47 #endif
48
49
50 /*******************************************************************
51
52 class wxJSONRefData
53
54 *******************************************************************/
55
56
57 /*! \class wxJSONRefData
58 \brief The reference counted JSON value data (internal use).
59
60 Starting from version 0.4, the JSON value class use the reference
61 counting tecnique (also know as \e copy-on-write) described in the
62 \b wxWidgets documentation in order to speed up processing.
63 The class is used internally by the wxJSONValue class which does
64 all processing.
65 To know more about COW see \ref json_internals_cow
66 */
67
68 #if defined( WXJSON_USE_VALUE_COUNTER )
69 // The progressive counter (used for debugging only)
70 int wxJSONRefData::sm_progr = 1;
71 #endif
72
73 //! Constructor.
wxJSONRefData()74 wxJSONRefData::wxJSONRefData()
75 {
76 m_lineNo = -1;
77 m_refCount = 1;
78 m_memBuff = 0;
79
80 #if defined( WXJSON_USE_VALUE_COUNTER )
81 m_progr = sm_progr;
82 ++sm_progr;
83 wxLogTrace( traceMask, _T("(%s) JSON refData ctor progr=%d"),
84 __PRETTY_FUNCTION__, m_progr);
85 #endif
86 }
87
88 // Dtor
~wxJSONRefData()89 wxJSONRefData::~wxJSONRefData()
90 {
91 if ( m_memBuff ) {
92 delete m_memBuff;
93 }
94 }
95
96 // Return the number of objects that reference this data.
97 int
GetRefCount() const98 wxJSONRefData::GetRefCount() const
99 {
100 return m_refCount;
101 }
102
103
104 /*******************************************************************
105
106 class wxJSONValue
107
108 *******************************************************************/
109
110
111 /*! \class wxJSONValue
112 \brief The JSON value class implementation.
113
114 This class holds a JSON value which may be of variuos types (see the
115 wxJSONType constants for a description of the types).
116 To know more about the internal representation of JSON values see
117 \ref pg_json_internals.
118
119 Starting from version 0.5 the wxJSON library supports 64-bits integers on
120 platforms that have native support for very large integers.
121 Note that the integer type is still stored as a generic wxJSONTYPE_(U)INT
122 constant regardless the size of the value but the JSON value class defines
123 functions in order to let the user know if an integer value fits in 16, 32
124 or 64 bit integer.
125 To know more about 64-bits integer support see \ref json_internals_integer
126
127 Storing values in a JSON value object of this class is very simple.
128 The following is an example:
129 \code
130 wxJSONValue v( _T( "A string")); // store a string value in the object
131 wxString s = v.AsString(); // get the string value
132
133 v = 12; // now 'v' contains an integer value
134 int i = v.AsInt(); // get the integer
135 \endcode
136
137 \par The C-string JSON value object
138
139 The wxJSONValue(const wxChar*) ctor allows you to create a JSON value
140 object that contains a string value which is stored as a
141 \e pointer-to-static-string.
142 Beware that this ctor DOES NOT copy the string: it only stores the
143 pointer in a data member and the pointed-to buffer is not deleted
144 by the dtor.
145 If the string is not static you have to use the wxJSONValue(const wxString&)
146 constructor.
147
148 Also note that this does NOT mean that the value stored in this JSON
149 object cannot change: you can assign whatever other value you want,
150 an integer, a double or an array of values.
151 What I intended is that the pointed-to string must exist for the lifetime
152 of the wxJSONValue object.
153 The following code is perfectly legal:
154 \code
155 wxJSONvalue aString( "this is a static string" );
156 aString = 10;
157 \endcode
158 To know more about this topic see \ref json_internals_cstring.
159
160 Starting from version 1.3 the class can hold binary memory buffers
161 as an extension to the JSON syntax. Memory buffers are stored as
162 \b wxMemoryBuffer objects which contain binary data. The class
163 uses reference counting for the copy and assignment operation but
164 it is not a \e copy-on-write structure.
165 To know more about memory buffers read \ref wxjson_tutorial_memorybuff
166
167 \sa the \ref wxjson_tutorial.
168 */
169
170
171 #if defined( WXJSON_USE_VALUE_COUNTER )
172 // The progressive counter (used for debugging only)
173 int wxJSONValue::sm_progr = 1;
174 #endif
175
176 //! Constructors.
177 /*!
178 The overloaded constructors allow the user to construct a JSON value
179 object that holds the specified value and type of value.
180 The default ctor construct a valid JSON object that constains a \b null
181 value.
182
183 If you want to create an \b invalid JSON value object you have to use the
184 \c wxJSONValue( wxJSONTYPE_INVALID ) ctor.
185 Note that this object is not a valid JSON value - to know more about this
186 topic see the SetType() function.
187
188 To create an empty array or key/value map use the following:
189 \code
190 wxJSONvalue v1( wxJSONTYPE_ARRAY );
191 wxJSONvalue v2( wxJSONTYPE_OBJECT );
192 \endcode
193 */
wxJSONValue()194 wxJSONValue::wxJSONValue()
195 {
196 m_refData = 0;
197 Init( wxJSONTYPE_NULL );
198 }
199
200 //! Initialize the JSON value class.
201 /*!
202 The function is called by the ctors and allocates a new instance of
203 the wxJSONRefData class and sets the type of the JSON value.
204 Note that only the type is set, not the value.
205 Also note that this function may be called from other memberfunctions
206 if the \c m_refData data member is NULL.
207 */
208 wxJSONRefData*
Init(wxJSONType type)209 wxJSONValue::Init( wxJSONType type )
210 {
211 wxJSONRefData* data = GetRefData();
212 if ( data != 0 ) {
213 UnRef();
214 }
215
216 // we allocate a new instance of the referenced data
217 data = new wxJSONRefData();
218 wxJSON_ASSERT( data );
219
220 // in release builds we do not have ASSERT so we check 'data' before
221 // using it
222 if ( data ) {
223 data->m_type = type;
224 data->m_commentPos = wxJSONVALUE_COMMENT_BEFORE;
225 }
226 SetRefData( data );
227
228 #if defined( WXJSON_USE_VALUE_COUNTER )
229 m_progr = sm_progr;
230 ++sm_progr;
231 wxLogTrace( cowTraceMask, _T("(%s) Init a new object progr=%d"),
232 __PRETTY_FUNCTION__, m_progr );
233 #endif
234 return data;
235 }
236
237
238 //! \overload wxJSONValue()
wxJSONValue(wxJSONType type)239 wxJSONValue::wxJSONValue( wxJSONType type )
240 {
241 m_refData = 0;
242 Init( type );
243 }
244
245 //! \overload wxJSONValue()
wxJSONValue(int i)246 wxJSONValue::wxJSONValue( int i )
247 {
248 m_refData = 0;
249 wxJSONRefData* data = Init( wxJSONTYPE_INT );
250 wxJSON_ASSERT( data );
251 if ( data != 0 ) {
252 // the 'VAL_INT' macro expands to 'm_valLong' or 'm_valInt64' depending
253 // on 64-bits integer support being enabled on not
254 data->m_value.VAL_INT = i;
255 }
256 }
257
258
259 //! \overload wxJSONValue()
wxJSONValue(unsigned int ui)260 wxJSONValue::wxJSONValue( unsigned int ui )
261 {
262 m_refData = 0;
263 wxJSONRefData* data = Init( wxJSONTYPE_UINT );
264 wxJSON_ASSERT( data );
265 if ( data != 0 ) {
266 // the 'VAL_UINT' macro expands to 'm_valULong' or 'm_valUInt64' depending
267 // on 64-bits integer support being enabled on not
268 data->m_value.VAL_UINT = ui;
269 }
270 }
271
272 //! \overload wxJSONValue()
wxJSONValue(short int i)273 wxJSONValue::wxJSONValue( short int i )
274 {
275 m_refData = 0;
276 wxJSONRefData* data = Init( wxJSONTYPE_INT );
277 wxJSON_ASSERT( data );
278 if ( data != 0 ) {
279 // the 'VAL_INT' macro expands to 'm_valLong' or 'm_valInt64' depending
280 // on 64-bits integer support being enabled on not
281 data->m_value.VAL_INT = i;
282 }
283 }
284
285
286 //! \overload wxJSONValue()
wxJSONValue(unsigned short ui)287 wxJSONValue::wxJSONValue( unsigned short ui )
288 {
289 m_refData = 0;
290 wxJSONRefData* data = Init( wxJSONTYPE_UINT );
291 wxJSON_ASSERT( data );
292 if ( data != 0 ) {
293 // the 'VAL_UINT' macro expands to 'm_valULong' or 'm_valUInt64' depending
294 // on 64-bits integer support being enabled on not
295 data->m_value.VAL_UINT = ui;
296 }
297 }
298
299 //! \overload wxJSONValue()
wxJSONValue(bool b)300 wxJSONValue::wxJSONValue( bool b )
301 {
302 m_refData = 0;
303 wxJSONRefData* data = Init( wxJSONTYPE_BOOL );
304 wxJSON_ASSERT( data );
305 if ( data != 0 ) {
306 data->m_value.m_valBool = b;
307 }
308 }
309
310 //! \overload wxJSONValue()
wxJSONValue(double d)311 wxJSONValue::wxJSONValue( double d )
312 {
313 m_refData = 0;
314 wxJSONRefData* data = Init( wxJSONTYPE_DOUBLE );
315 wxJSON_ASSERT( data );
316 if ( data != 0 ) {
317 data->m_value.m_valDouble = d;
318 }
319 }
320
321 //! \overload wxJSONValue()
wxJSONValue(const wxChar * str)322 wxJSONValue::wxJSONValue( const wxChar* str )
323 {
324 m_refData = 0;
325 wxJSONRefData* data = Init( wxJSONTYPE_CSTRING );
326 wxJSON_ASSERT( data );
327 if ( data != 0 ) {
328 #if !defined( WXJSON_USE_CSTRING )
329 data->m_type = wxJSONTYPE_STRING;
330 data->m_valString.assign( str );
331 #else
332 data->m_value.m_valCString = str;
333 #endif
334 }
335 }
336
337 //! \overload wxJSONValue()
wxJSONValue(const wxString & str)338 wxJSONValue::wxJSONValue( const wxString& str )
339 {
340 m_refData = 0;
341 wxJSONRefData* data = Init( wxJSONTYPE_STRING );
342 wxJSON_ASSERT( data );
343 if ( data != 0 ) {
344 data->m_valString.assign( str );
345 }
346 }
347
348 //! \overload wxJSONValue()
wxJSONValue(long int l)349 wxJSONValue::wxJSONValue( long int l )
350 {
351 m_refData = 0;
352 wxJSONRefData* data = Init( wxJSONTYPE_INT );
353 wxJSON_ASSERT( data );
354 if ( data != 0 ) {
355 data->m_value.VAL_INT = l;
356 }
357 }
358
359 //! \overload wxJSONValue()
wxJSONValue(unsigned long int ul)360 wxJSONValue::wxJSONValue( unsigned long int ul )
361 {
362 m_refData = 0;
363 wxJSONRefData* data = Init( wxJSONTYPE_UINT );
364 wxJSON_ASSERT( data );
365 if ( data != 0 ) {
366 data->m_value.VAL_UINT = ul;
367 }
368 }
369
370 //! Construct a JSON value object of type \e memory \e buffer
371 /*!
372 Note that this ctor makes a deep copy of \c buff so changes made
373 to the original buffer does not reflect to the buffer stored in this
374 JSON value.
375 */
wxJSONValue(const wxMemoryBuffer & buff)376 wxJSONValue::wxJSONValue( const wxMemoryBuffer& buff )
377 {
378 m_refData = 0;
379 wxJSONRefData* data = Init( wxJSONTYPE_MEMORYBUFF );
380 wxJSON_ASSERT( data );
381 if ( data != 0 ) {
382 data->m_memBuff = new wxMemoryBuffer();
383 const void* ptr = buff.GetData();
384 size_t buffLen = buff.GetDataLen();
385 if ( buffLen > 0 ) {
386 data->m_memBuff->AppendData( ptr, buffLen );
387 }
388 }
389 }
390
391 //! Construct a JSON value object of type \e memory \e buffer
392 /*!
393 Note that this ctor makes a deep copy of \c buff so changes made
394 to the original buffer does not reflect to the buffer stored in this
395 JSON value.
396 */
wxJSONValue(const void * buff,size_t len)397 wxJSONValue::wxJSONValue( const void* buff, size_t len )
398 {
399 m_refData = 0;
400 wxJSONRefData* data = Init( wxJSONTYPE_MEMORYBUFF );
401 wxJSON_ASSERT( data );
402 if ( data != 0 && len > 0 ) {
403 data->m_memBuff = new wxMemoryBuffer();
404 data->m_memBuff->AppendData( buff, len );
405 }
406 }
407
408 //! Copy constructor
409 /*!
410 The function copies the content of \c other in this
411 object.
412 Note that the JSON value object is not really copied;
413 the function calls Ref() in order to increment
414 the reference count of the \c wxJSONRefData structure.
415 */
wxJSONValue(const wxJSONValue & other)416 wxJSONValue::wxJSONValue( const wxJSONValue& other )
417 {
418 m_refData = 0;
419 Ref( other );
420
421 // the progressive counter of the ctor is not copied from
422 // the other wxJSONValue object: only data is shared, the
423 // progressive counter is not shared because this object
424 // is a copy of 'other' and it has its own progressive
425 #if defined( WXJSON_USE_VALUE_COUNTER )
426 m_progr = sm_progr;
427 ++sm_progr;
428 wxLogTrace( cowTraceMask, _T("(%s) Copy ctor - progr=%d other progr=%d"),
429 __PRETTY_FUNCTION__, m_progr, other.m_progr );
430 #endif
431 }
432
433
434 //! Dtor - calls UnRef().
~wxJSONValue()435 wxJSONValue::~wxJSONValue()
436 {
437 UnRef();
438 }
439
440
441 // functions for retreiving the value type: they are all 'const'
442
443
444 //! Return the type of the value stored in the object.
445 /*!
446 This function is the only one that does not ASSERT that the
447 \c m_refData data member is not NULL.
448 In fact, if the JSON value object does not contain a pointer
449 to a wxJSONRefData structure, the function returns the
450 wxJSONTYPE_INVALID constant which represent an invalid JSON value object.
451 Also note that the pointer to the referenced data structure
452 should NEVER be NULL.
453
454 \par Integer types
455
456 Integers are stored internally in a \b signed/unsigned \b long \b int
457 or, on platforms that support 64-bits integers, in a
458 \b wx(U)Int64 data type.
459 When constructed, it is assigned a generic integer type that only
460 depends on the sign: wxJSON_(U)INT regardless the size of the
461 stored value.
462
463 This function can be used to know the actual size requirement
464 of the stored value and how it can be retrieved. The value
465 returned by this function is:
466
467 - for signed integers:
468 - \b wxJSONTYPE_SHORT if the value is between SHORT_MIN and SHORT_MAX
469 - \b wxJSONTYPE_LONG if the value is between LONG_MIN and LONG_MAX
470 and greater than SHORT_MAX and less than SHORT_MIN
471 - \b wxJSONTYPE_INT64 if the value is greater than LONG_MAX and
472 less than LONG_MIN
473
474 - for unsigned integers:
475 - \b wxJSONTYPE_USHORT if the value is between 0 and USHORT_MAX
476 - \b wxJSONTYPE_ULONG if the value is between 0 and ULONG_MAX
477 and greater than USHORT_MAX
478 - \b wxJSONTYPE_UINT64 if the value is greater than ULONG_MAX
479
480 Note that this function never returns the wxJSONTYPE_(U)INT constant
481 because the \b int data type may have the same width as SHORT or LONG
482 depending on the platform.
483 This does not mean that you cannot use \b int as the return value: if
484 you use \b wxWidgets to develop application in only one platform, you
485 can use \b int because you know the size of the data type.
486 Otherwise, if is preferable to always use \b long instead of \b int.
487
488 Also note that the class defines the \c IsInt() memberfunction which
489 works fine regardless the actual width of the \b int data type.
490 This function returns TRUE if the stored value fits in a \b int data
491 type whatever its size is on the current platform (16 or 32-bits).
492
493 \sa SetType IsInt
494 */
495 wxJSONType
GetType() const496 wxJSONValue::GetType() const
497 {
498 wxJSONRefData* data = GetRefData();
499 wxJSONType type = wxJSONTYPE_INVALID;
500 if ( data ) {
501 type = data->m_type;
502
503 // for integers and unsigned ints check the storage requirements
504 // note that ints are stored as 'long' or as 'long long'
505 switch ( type ) {
506 case wxJSONTYPE_INT :
507 // check if the integer fits in a SHORT INT
508 if ( data->m_value.VAL_INT >= SHORT_MIN &&
509 data->m_value.VAL_INT <= SHORT_MAX ) {
510 type = wxJSONTYPE_SHORT;
511 }
512 // check if the value fits in LONG INT
513 else if ( data->m_value.VAL_INT >= LONG_MIN
514 && data->m_value.VAL_INT <= LONG_MAX ) {
515 type = wxJSONTYPE_LONG;
516 }
517 else {
518 type = wxJSONTYPE_INT64;
519 }
520 break;
521
522 case wxJSONTYPE_UINT :
523 if ( data->m_value.VAL_UINT <= USHORT_MAX ) {
524 type = wxJSONTYPE_USHORT;
525 }
526 else if ( data->m_value.VAL_UINT <= ULONG_MAX ) {
527 type = wxJSONTYPE_ULONG;
528 }
529 else {
530 type = wxJSONTYPE_UINT64;
531 }
532 break;
533
534 default :
535 break;
536 }
537 }
538 return type;
539 }
540
541
542 //! Return TRUE if the type of the value is wxJSONTYPE_NULL.
543 bool
IsNull() const544 wxJSONValue::IsNull() const
545 {
546 wxJSONType type = GetType();
547 bool r = false;
548 if ( type == wxJSONTYPE_NULL ) {
549 r = true;
550 }
551 return r;
552 }
553
554
555 //! Return TRUE if the value stored is valid
556 /*!
557 The function returns TRUE if the wxJSONValue object was correctly
558 initialized - that is it contains a valid value.
559 A JSON object is valid if its type is not equal to wxJSONTYPE_INVALID.
560 Please note that the default ctor of wxJSONValue constructs a \b valid
561 JSON object of type \b null.
562 To create an invalid object you have to use;
563 \code
564 wxJSONValue v( wxJSONTYPE_INVALID );
565 \endcode
566 */
567 bool
IsValid() const568 wxJSONValue::IsValid() const
569 {
570 wxJSONType type = GetType();
571 bool r = false;
572 if ( type != wxJSONTYPE_INVALID ) {
573 r = true;
574 }
575 return r;
576 }
577
578 //! Return TRUE if the type of the value stored is integer.
579 /*!
580 This function returns TRUE if the stored value is of
581 type signed integer and the numeric value fits in a
582 \b int data type.
583 In other words, the function returns TRUE if the \c wxJSONRefData::m_type
584 data member is of type \c wxJSONTYPE_INT and:
585
586 \code
587 INT_MIN <= m_value <= INT_MAX
588 \endcode
589
590 Note that if you are developing cross-platform applications you should never
591 use \b int as the integer data type but \b long for 32-bits integers and
592 \b short for 16-bits integers.
593 This is because the \b int data type may have different width on different
594 platforms.
595 Regardless the widht of the data type (16 or 32 bits), the function returns
596 the correct result because it relies on the INT_MAX and INT_MIN macros.
597
598 \sa \ref json_internals_integer
599 */
600 bool
IsInt() const601 wxJSONValue::IsInt() const
602 {
603 wxJSONType type = GetType();
604 bool r = false;
605 // if the type is SHORT the value fits into an INT, too
606 if ( type == wxJSONTYPE_SHORT ) {
607 r = true;
608 }
609 else if ( type == wxJSONTYPE_LONG ) {
610 // in case of LONG, check if the bit width is the same
611 if ( INT_MAX == LONG_MAX ) {
612 r = true;
613 }
614 }
615 return r;
616 }
617
618 //! Return TRUE if the type of the value stored is 16-bit integer.
619 /*!
620 This function returns TRUE if the stored value is of
621 type signed integer and the numeric value fits in a
622 \b short \b int data type (16-bit integer).
623 In other words, the function returns TRUE if the \c wxJSONRefData::m_type
624 data member is of type \c wxJSONTYPE_INT and:
625
626 \code
627 SHORT_MIN <= m_value <= SHORT_MAX
628 \endcode
629
630 \sa \ref json_internals_integer
631 */
632 bool
IsShort() const633 wxJSONValue::IsShort() const
634 {
635 wxJSONType type = GetType();
636 bool r = false;
637 if ( type == wxJSONTYPE_SHORT ) {
638 r = true;
639 }
640 return r;
641 }
642
643 //! Return TRUE if the type of the value stored is a unsigned int.
644 /*!
645 This function returns TRUE if the stored value is of
646 type unsigned integer and the numeric value fits int a
647 \b int data type.
648 In other words, the function returns TRUE if the \c wxJSONRefData::m_type
649 data member is of type \c wxJSONTYPE_UINT and:
650
651 \code
652 0 <= m_value <= UINT_MAX
653 \endcode
654
655 Note that if you are developing cross-platform applications you should never
656 use \b unsigned \b int as the integer data type but \b unsigned \b long for
657 32-bits integers and \b unsigned \b short for 16-bits integers.
658 This is because the \b unsigned \b int data type may have different width
659 on different platforms.
660 Regardless the widht of the data type (16 or 32 bits), the function returns
661 the correct result because it relies on the UINT_MAX macro.
662
663
664 \sa \ref json_internals_integer
665 */
666 bool
IsUInt() const667 wxJSONValue::IsUInt() const
668 {
669 wxJSONType type = GetType();
670 bool r = false;
671 if ( type == wxJSONTYPE_USHORT ) {
672 r = true;
673 }
674 else if ( type == wxJSONTYPE_ULONG ) {
675 if ( INT_MAX == LONG_MAX ) {
676 r = true;
677 }
678 }
679 return r;
680 }
681
682 //! Return TRUE if the type of the value stored is a unsigned short.
683 /*!
684 This function returns TRUE if the stored value is of
685 type unsigned integer and the numeric value fits in a
686 \b unsigned \b short \b int data type.
687 In other words, the function returns TRUE if the \c wxJSONRefData::m_type
688 data member is of type \c wxJSONTYPE_UINT and:
689
690 \code
691 0 <= m_value <= USHORT_MAX
692 \endcode
693
694 \sa \ref json_internals_integer
695 */
696 bool
IsUShort() const697 wxJSONValue::IsUShort() const
698 {
699 wxJSONType type = GetType();
700 bool r = false;
701 if ( type == wxJSONTYPE_USHORT ) {
702 r = true;
703 }
704 return r;
705 }
706
707
708 //! Return TRUE if the stored value is an integer which fits in a long int
709 /*!
710 This function returns TRUE if the stored value is of
711 type signed LONG integer and the numeric value fits int a
712 \b long \b int data type.
713 In other words, the function returns TRUE if the \c wxJSONRefData::m_type
714 data member is of type \c wxJSONTYPE_INT and:
715
716 \code
717 LONG_MIN <= m_value <= LONG_MAX
718 \endcode
719
720 \sa \ref json_internals_integer
721 */
722 bool
IsLong() const723 wxJSONValue::IsLong() const
724 {
725 wxJSONType type = GetType();
726 bool r = false;
727 if ( type == wxJSONTYPE_LONG || type == wxJSONTYPE_SHORT ) {
728 r = true;
729 }
730 return r;
731 }
732
733 //! Return TRUE if the stored value is an integer which fits in a unsigned long int
734 /*!
735 This function returns TRUE if the stored value is of
736 type unsigned LONG integer and the numeric value fits int a
737 \b unsigned \b long \b int data type.
738 In other words, the function returns TRUE if the \c wxJSONRefData::m_type
739 data member is of type \c wxJSONTYPE_UINT and:
740
741 \code
742 0 <= m_value <= ULONG_MAX
743 \endcode
744
745 \sa \ref json_internals_integer
746 */
747 bool
IsULong() const748 wxJSONValue::IsULong() const
749 {
750 wxJSONType type = GetType();
751 bool r = false;
752 if ( type == wxJSONTYPE_ULONG || type == wxJSONTYPE_USHORT ) {
753 r = true;
754 }
755 return r;
756 }
757
758
759
760 //! Return TRUE if the type of the value stored is a boolean.
761 bool
IsBool() const762 wxJSONValue::IsBool() const
763 {
764 wxJSONType type = GetType();
765 bool r = false;
766 if ( type == wxJSONTYPE_BOOL ) {
767 r = true;
768 }
769 return r;
770 }
771
772 //! Return TRUE if the type of the value stored is a double.
773 bool
IsDouble() const774 wxJSONValue::IsDouble() const
775 {
776 wxJSONType type = GetType();
777 bool r = false;
778 if ( type == wxJSONTYPE_DOUBLE ) {
779 r = true;
780 }
781 return r;
782 }
783
784 //! Return TRUE if the type of the value stored is a wxString object.
785 bool
IsString() const786 wxJSONValue::IsString() const
787 {
788 wxJSONType type = GetType();
789 bool r = false;
790 if ( type == wxJSONTYPE_STRING ) {
791 r = true;
792 }
793 return r;
794 }
795
796 //! Return TRUE if the type of the value stored is a pointer to a static C string.
797 /*!
798 This function returns TRUE if, and only if the stored value is a
799 pointer to a static C-string and the C-string storage is enabled in
800 the wxJSON library.
801 By default, C-string storage is not enabled in the library so this
802 function always returns FALSE.
803 To know more about C-strings read \ref json_internals_cstring
804 */
805 bool
IsCString() const806 wxJSONValue::IsCString() const
807 {
808 wxJSONType type = GetType();
809 bool r = false;
810 if ( type == wxJSONTYPE_CSTRING ) {
811 r = true;
812 }
813 return r;
814 }
815
816 //! Return TRUE if the type of the value stored is an array type.
817 bool
IsArray() const818 wxJSONValue::IsArray() const
819 {
820 wxJSONType type = GetType();
821 bool r = false;
822 if ( type == wxJSONTYPE_ARRAY ) {
823 r = true;
824 }
825 return r;
826 }
827
828 //! Return TRUE if the type of this value is a key/value map.
829 bool
IsObject() const830 wxJSONValue::IsObject() const
831 {
832 wxJSONType type = GetType();
833 bool r = false;
834 if ( type == wxJSONTYPE_OBJECT ) {
835 r = true;
836 }
837 return r;
838 }
839
840 //! Return TRUE if the type of this value is a binary memory buffer.
841 bool
IsMemoryBuff() const842 wxJSONValue::IsMemoryBuff() const
843 {
844 wxJSONType type = GetType();
845 bool r = false;
846 if ( type == wxJSONTYPE_MEMORYBUFF ) {
847 r = true;
848 }
849 return r;
850 }
851
852
853
854 // get the stored value; all these functions are 'const'
855
856 //! Return the stored value as an integer.
857 /*!
858 The function returns the stored value as an integer.
859 Note that the function does not check that the type of the
860 value is actually an integer and it just returns the content
861 of the wxJSONValueHolder union.
862 However, in debug builds, the function ASSERTs that the
863 type of the stored value \c IsInt().
864
865 \sa \ref json_internals_integer
866 \sa \ref wxjson_tutorial_get
867 */
868 int
AsInt() const869 wxJSONValue::AsInt() const
870 {
871 wxJSONRefData* data = GetRefData();
872 wxJSON_ASSERT( data );
873 int i = (int) data->m_value.VAL_INT;
874
875 wxJSON_ASSERT( IsInt());
876 return i;
877 }
878
879 //! Return the stored value as a boolean.
880 /*!
881 The function returns the stored value as a boolean.
882 Note that the function does not check that the type of the
883 value is actually a boolean and it just returns the content
884 of the wxJSONValueHolder union.
885 However, in debug builds, the function ASSERTs that the
886 type of the stored value is wxJSONTYPE_BOOL.
887
888 \sa \ref wxjson_tutorial_get
889 */
890 bool
AsBool() const891 wxJSONValue::AsBool() const
892 {
893 wxJSONRefData* data = GetRefData();
894 wxJSON_ASSERT( data );
895 wxJSON_ASSERT( data->m_type == wxJSONTYPE_BOOL );
896 return data->m_value.m_valBool;
897 }
898
899 //! Return the stored value as a double.
900 /*!
901 The function returns the stored value as a double.
902 Note that the function does not check that the type of the
903 value is actually a double and it just returns the content
904 of the wxJSONValueHolder union as if it was a double.
905 However, in debug builds, the function ASSERTs that the
906 type of the stored value \c IsDouble().
907
908 \sa \ref wxjson_tutorial_get
909 */
910 double
AsDouble() const911 wxJSONValue::AsDouble() const
912 {
913 wxJSONRefData* data = GetRefData();
914 wxJSON_ASSERT( data );
915 double d = data->m_value.m_valDouble;
916 wxJSON_ASSERT( IsDouble());
917 return d;
918 }
919
920
921 //! Return the stored value as a wxWidget's string.
922 /*!
923 The function returns a string representation of the value
924 stored in the JSON object.
925 All value types are converted to a string by this function
926 and returned as a string:
927
928 \li For integer the string is the string representation of
929 the numerical value in decimal notation; the function uses the
930 \b wxString::Printf() function for the conversion
931
932 \li for doubles, the value is converted to a string using the
933 \b wxString::Printf("%.10g") function; the format string specifies
934 a precision of ten decimal digits and suppress trailing ZEROes
935
936 \li for booleans the string returned is: \b true or \b false.
937
938 \li if the value is a NULL value the \b null literal string is returned.
939
940 \li if the value is of type wxJSONTYPE_INVALID, the literal string \b <invalid>
941 is returned. Note that this is NOT a valid JSON text.
942
943 \li if the value is of type wxJSONTYPE_MEMORYBUFF the string returned contains the
944 hexadecimal digits of the first 5 bytes preceeded by the length of the buffer,
945 enclosed in parenthesis
946
947 If the value is an array or map, the returned string is the number of
948 elements is the array/object enclosed in the JSON special characters that
949 identifies the array/object. Example:
950
951 \code
952 [0] // an empty array
953 {12} // an object of 12 elements
954 \endcode
955
956 \sa \ref wxjson_tutorial_get
957 */
958 wxString
AsString() const959 wxJSONValue::AsString() const
960 {
961 wxJSONRefData* data = GetRefData();
962 wxJSON_ASSERT( data );
963 wxString s;
964 int size = Size();
965 switch ( data->m_type ) {
966 case wxJSONTYPE_STRING :
967 s.assign( data->m_valString);
968 break;
969 case wxJSONTYPE_CSTRING :
970 s.assign( data->m_value.m_valCString);
971 break;
972 case wxJSONTYPE_INT :
973 #if defined( wxJSON_64BIT_INT )
974 s.Printf( _T("%") compatibleLongLongFmtSpec _T("i"),
975 data->m_value.m_valInt64 );
976 #else
977 s.Printf( _T("%ld"), data->m_value.m_valLong );
978 #endif
979 break;
980 case wxJSONTYPE_UINT :
981 #if defined( wxJSON_64BIT_INT )
982 s.Printf( _T("%") compatibleLongLongFmtSpec _T("u"),
983 data->m_value.m_valUInt64 );
984 #else
985 s.Printf( _T("%lu"), data->m_value.m_valULong );
986 #endif
987 break;
988 case wxJSONTYPE_DOUBLE :
989 s.Printf( _T("%.10g"), data->m_value.m_valDouble );
990 break;
991 case wxJSONTYPE_BOOL :
992 s.assign( ( data->m_value.m_valBool ?
993 _T("true") : _T("false") ));
994 break;
995 case wxJSONTYPE_NULL :
996 s.assign( _T( "null"));
997 break;
998 case wxJSONTYPE_INVALID :
999 s.assign( _T( "<invalid>"));
1000 break;
1001 case wxJSONTYPE_ARRAY :
1002 s.Printf( _T("[%d]"), size );
1003 break;
1004 case wxJSONTYPE_OBJECT :
1005 s.Printf( _T("{%d}"), size );
1006 break;
1007 case wxJSONTYPE_MEMORYBUFF :
1008 s = MemoryBuffToString( *(data->m_memBuff), 5 );
1009 break;
1010 default :
1011 s.assign( _T( "wxJSONValue::AsString(): Unknown JSON type \'"));
1012 s.append( TypeToString( data->m_type ));
1013 s.append( _T( "\'" ));
1014 wxFAIL_MSG( s );
1015 break;
1016 }
1017 return s;
1018 }
1019
1020 //! Return the stored value as a pointer to a static C string.
1021 /*!
1022 If the type of the value is stored as a C-string data type the
1023 function just returns that pointer.
1024 If the stored value is a wxString object, the function returns the
1025 pointer returned by the \b wxString::c_str() function.
1026 If the stored value is of all other JSON types, the functions returns a NULL pointer.
1027
1028 Note that in versions prior to 0.5, the
1029 function returned a NULL pointer also if the value is a \c wxString object.
1030
1031 \sa \ref json_internals_cstring
1032 \sa \ref wxjson_tutorial_get
1033
1034 */
1035 const wxChar*
AsCString() const1036 wxJSONValue::AsCString() const
1037 {
1038 const wxChar* s = 0;
1039 wxJSONRefData* data = GetRefData();
1040 wxJSON_ASSERT( data );
1041 switch ( data->m_type ) {
1042 case wxJSONTYPE_CSTRING :
1043 s = data->m_value.m_valCString;
1044 break;
1045 case wxJSONTYPE_STRING :
1046 s = data->m_valString.c_str();
1047 break;
1048 default :
1049 break;
1050 }
1051 return s;
1052 }
1053
1054
1055 //! Return the stored value as a unsigned int.
1056 /*!
1057 The function returns the stored value as a unsigned integer.
1058 Note that the function does not check that the type of the
1059 value is actually a unsigned integer and it just returns the content
1060 of the wxJSONValueHolder union.
1061 However, in debug builds, the function ASSERTs that the
1062 type of the stored value is wxJSONTYPE_UINT.
1063
1064 \sa \ref json_internals_integer
1065 \sa \ref wxjson_tutorial_get
1066 */
1067 unsigned int
AsUInt() const1068 wxJSONValue::AsUInt() const
1069 {
1070 wxJSONRefData* data = GetRefData();
1071 wxJSON_ASSERT( data );
1072 unsigned int ui = (unsigned) data->m_value.VAL_UINT;
1073
1074 wxJSON_ASSERT( IsUInt());
1075 return ui;
1076 }
1077
1078
1079 //! Returns the value as a long integer
1080 /*!
1081 The function returns the stored value as a long integer.
1082 Note that the function does not check that the type of the
1083 value is actually a long integer and it just returns the content
1084 of the wxJSONValueHolder union.
1085 However, in debug builds, the function ASSERTs that the
1086 type of the stored value \c IsLong().
1087
1088 \sa \ref json_internals_integer
1089 \sa \ref wxjson_tutorial_get
1090 */
1091 long int
AsLong() const1092 wxJSONValue::AsLong() const
1093 {
1094 long int l;
1095 wxJSONRefData* data = GetRefData();
1096 wxJSON_ASSERT( data );
1097 l = (long) data->m_value.VAL_INT;
1098
1099 wxJSON_ASSERT( IsLong());
1100 return l;
1101 }
1102
1103 //! Returns the value as a unsigned long integer
1104 /*!
1105 The function returns the stored value as a unsigned long integer.
1106 Note that the function does not check that the type of the
1107 value is actually a unsigned long integer and it just returns the content
1108 of the wxJSONValueHolder union.
1109 However, in debug builds, the function ASSERTs that the
1110 type of the stored value \c IsLong().
1111
1112 \sa \ref json_internals_integer
1113 \sa \ref wxjson_tutorial_get
1114 */
1115 unsigned long int
AsULong() const1116 wxJSONValue::AsULong() const
1117 {
1118 wxJSONRefData* data = GetRefData();
1119 wxJSON_ASSERT( data );
1120 unsigned long int ul = (unsigned long) data->m_value.VAL_UINT;
1121
1122 wxJSON_ASSERT( IsULong()); // expands only in debug builds
1123 return ul;
1124 }
1125
1126
1127 //! Returns the value as a short integer
1128 /*!
1129 The function returns the stored value as a short integer.
1130 Note that the function does not check that the type of the
1131 value is actually a short integer and it just returns the content
1132 of the wxJSONValueHolder union.
1133 However, in debug builds, the function ASSERTs that the
1134 type of the stored value \c IsShort().
1135
1136 \sa \ref json_internals_integer
1137 \sa \ref wxjson_tutorial_get
1138 */
1139 short int
AsShort() const1140 wxJSONValue::AsShort() const
1141 {
1142 short int i;
1143 wxJSONRefData* data = GetRefData();
1144 wxJSON_ASSERT( data );
1145 i = (short) data->m_value.VAL_INT;
1146
1147 wxJSON_ASSERT( IsShort());
1148 return i;
1149 }
1150
1151 //! Returns the value as a unsigned short integer
1152 /*!
1153 The function returns the stored value as a unsigned short integer.
1154 Note that the function does not check that the type of the
1155 value is actually a unsigned short and it just returns the content
1156 of the wxJSONValueHolder union.
1157 However, in debug builds, the function ASSERTs that the
1158 type of the stored value \c IsUShort().
1159
1160 \sa \ref json_internals_integer
1161 \sa \ref wxjson_tutorial_get
1162 */
1163 unsigned short
AsUShort() const1164 wxJSONValue::AsUShort() const
1165 {
1166 unsigned short ui;
1167 wxJSONRefData* data = GetRefData();
1168 wxJSON_ASSERT( data );
1169 ui = (unsigned short) data->m_value.VAL_UINT;
1170
1171 wxJSON_ASSERT( IsUShort());
1172 return ui;
1173 }
1174
1175
1176
1177 //! Stores the value of this object in the provided argument
1178 /*!
1179 The functions of the form \c AsXxxxxx(T&) are the same as the \c AsXxxxxxx()
1180 but store the value in the provided argument and return TRUE if the value of
1181 this object is of the correct type.
1182 By using these functions you can get the value and test if the JSON value is
1183 of the expected type in only one step.
1184 For example:
1185 \code
1186 int i; wxJSONValue v(10);
1187 if ( !v.AsInt( i )) {
1188 cout << "Error: value is not of the expected type";
1189 }
1190 \endcode
1191 This is the same as:
1192 \code
1193 int i; wxJSONValue v(10);
1194 if ( v.IsInt() {
1195 i = v.AsInt();
1196 }
1197 else {
1198 cout << "Error: value is not of the expected type";
1199 }
1200 \endcode
1201 Thanks to \b catalin who has suggested this new feature.
1202 */
1203 bool
AsInt(int & i) const1204 wxJSONValue::AsInt( int& i ) const
1205 {
1206 bool r = false;
1207 if ( IsInt() ) {
1208 i = AsInt();
1209 r = true;
1210 }
1211 return r;
1212 }
1213
1214 bool
AsUInt(unsigned int & ui) const1215 wxJSONValue::AsUInt( unsigned int& ui ) const
1216 {
1217 bool r = false;
1218 if ( IsUInt() ) {
1219 ui = AsUInt();
1220 r = true;
1221 }
1222 return r;
1223 }
1224
1225 bool
AsShort(short int & s) const1226 wxJSONValue::AsShort( short int& s ) const
1227 {
1228 bool r = false;
1229 if ( IsShort() ) {
1230 s = AsShort();
1231 r = true;
1232 }
1233 return r;
1234 }
1235
1236 bool
AsUShort(unsigned short & us) const1237 wxJSONValue::AsUShort( unsigned short& us ) const
1238 {
1239 bool r = false;
1240 if ( IsUShort() ) {
1241 us = AsUShort();
1242 r = true;
1243 }
1244 return r;
1245 }
1246
1247 bool
AsLong(long int & l) const1248 wxJSONValue::AsLong( long int& l ) const
1249 {
1250 bool r = false;
1251 if ( IsLong() ) {
1252 l = AsLong();
1253 r = true;
1254 }
1255 return r;
1256 }
1257
1258 bool
AsULong(unsigned long & ul) const1259 wxJSONValue::AsULong( unsigned long& ul ) const
1260 {
1261 bool r = false;
1262 if ( IsULong() ) {
1263 ul = AsULong();
1264 r = true;
1265 }
1266 return r;
1267 }
1268
1269
1270 bool
AsBool(bool & b) const1271 wxJSONValue::AsBool( bool& b ) const
1272 {
1273 bool r = false;
1274 if ( IsBool() ) {
1275 b = AsBool();
1276 r = true;
1277 }
1278 return r;
1279 }
1280
1281 bool
AsDouble(double & d) const1282 wxJSONValue::AsDouble( double& d ) const
1283 {
1284 bool r = false;
1285 if ( IsDouble() ) {
1286 d = AsDouble();
1287 r = true;
1288 }
1289 return r;
1290 }
1291
1292 //! Return this string value in the provided argument
1293 /*!
1294 This function is different from \c AsString because the latter always returns
1295 a string also when this object does not contain a string. In that case, a string
1296 representation of this value is returned.
1297 This function, instead, returns TRUE only if this object contains a string, that is
1298 only if \c IsString() returns TRUE.
1299 Also note that the string value is only stored in \c str if this object actually
1300 contains a \b string or \b c-string value.
1301 \c str will never contain a string representation of other types.
1302 */
1303 bool
AsString(wxString & str) const1304 wxJSONValue::AsString( wxString& str ) const
1305 {
1306 bool r = IsString();
1307 if ( r ) {
1308 str = AsString();
1309 }
1310 return r;
1311 }
1312
1313 bool
AsCString(wxChar * ch) const1314 wxJSONValue::AsCString( wxChar* ch ) const
1315 {
1316 bool r = IsCString();
1317 if ( r ) {
1318 ch = (wxChar*) AsCString();
1319 }
1320 return r;
1321 }
1322
1323 //! Returns the value as a memory buffer
1324 /*!
1325 The function returns the \e memory \e buffer object stored in
1326 this JSON object.
1327 Note that as of wxWidgets 2.8 and 2.9 the \b wxMemoryBuffer object uses
1328 reference counting when copying the actual buffer but the class itself
1329 is not a \e copy-on-write structure so changes made to one buffer affects
1330 all other copies made from it.
1331 This means that if you make a change to the returned copy of the memory
1332 buffer, the change affects also the memory buffer stored in this JSON value.
1333
1334 If this JSON object does not contain a \e wxJSONTYPE_MEMORYBUFF type
1335 the function returns an empty memory buffer object.
1336 An empty memory buffer is also returned if this JSON
1337 type contains a valid, empty memory buffer.
1338 You have to use the IsMemoryBuff() function to known the type of the
1339 JSON value contained in this object, or the overloaded version of
1340 this function.
1341 */
1342 wxMemoryBuffer
AsMemoryBuff() const1343 wxJSONValue::AsMemoryBuff() const
1344 {
1345 wxJSONRefData* data = GetRefData();
1346 wxJSON_ASSERT( data );
1347 wxMemoryBuffer buff;
1348 if ( data->m_memBuff ) {
1349 buff = *(data->m_memBuff);
1350 }
1351
1352 wxJSON_ASSERT( IsMemoryBuff());
1353 return buff;
1354 }
1355
1356
1357 //! Returns the value as a memory buffer
1358 /*!
1359 The function returns the \e memory \e buffer object stored in
1360 this JSON object.
1361 Note that as of wxWidgets 2.8 and 2.9 the \b wxMemoryBuffer object uses
1362 reference counting when copying the actual buffer but the class itself
1363 is not a \e copy-on-write structure so changes made to one buffer affects
1364 all other copies made from it.
1365 This means that if you make a change to the returned copy of the memory
1366 buffer, the change affects also the memory buffer stored in this JSON value.
1367
1368 If this JSON object does not contain a \e wxJSONTYPE_MEMORYBUFF type
1369 the function returns an empty memory buffer object.
1370 An empty memory buffer is also returned if this JSON
1371 type contains a valid, empty memory buffer.
1372 You have to use the IsMemoryBuff() function to known the type of the
1373 JSON value contained in this object, or the overloaded version of
1374 this function.
1375 */
1376 bool
AsMemoryBuff(wxMemoryBuffer & buff) const1377 wxJSONValue::AsMemoryBuff( wxMemoryBuffer& buff ) const
1378 {
1379 bool r = IsMemoryBuff();
1380 if ( r ) {
1381 buff = AsMemoryBuff();
1382 }
1383 return r;
1384 }
1385
1386
1387 // internal use
1388
1389 //! Return the stored value as a map object.
1390 /*!
1391 This function is for testing and debugging purposes and you shold never use it.
1392 To retreive values from an array or map JSON object use the \c Item() or ItemAt()
1393 memberfunctions or the subscript operator.
1394 If the stored value is not a map type, returns a NULL pointer.
1395 */
1396 const wxJSONInternalMap*
AsMap() const1397 wxJSONValue::AsMap() const
1398 {
1399 wxJSONRefData* data = GetRefData();
1400 wxJSON_ASSERT( data );
1401
1402 const wxJSONInternalMap* v = 0;
1403 if ( data->m_type == wxJSONTYPE_OBJECT ) {
1404 v = &( data->m_valMap );
1405 }
1406 return v;
1407 }
1408
1409 //! Return the stored value as an array object.
1410 /*!
1411 This function is for testing and debugging purposes and you shold never use it.
1412 To retreive values from an array or map JSON object use the \c Item() or ItemAt()
1413 memberfunctions or the subscript operator.
1414 If the stored value is not an array type, returns a NULL pointer.
1415 */
1416 const wxJSONInternalArray*
AsArray() const1417 wxJSONValue::AsArray() const
1418 {
1419 wxJSONRefData* data = GetRefData();
1420 wxJSON_ASSERT( data );
1421
1422 const wxJSONInternalArray* v = 0;
1423 if ( data->m_type == wxJSONTYPE_ARRAY ) {
1424 v = &( data->m_valArray );
1425 }
1426 return v;
1427 }
1428
1429 // retrieve the members and other info
1430
1431
1432 //! Return TRUE if the object contains an element at the specified index.
1433 /*!
1434 If the stoerd value is not an array or a map, the function returns FALSE.
1435 */
1436 bool
HasMember(unsigned index) const1437 wxJSONValue::HasMember( unsigned index ) const
1438 {
1439 bool r = false;
1440 int size = Size();
1441 if ( index < (unsigned) size ) {
1442 r = true;
1443 }
1444 return r;
1445 }
1446
1447 //! Return TRUE if the object contains an element at the specified key.
1448 /*!
1449 If the stored value is not a key/map map, the function returns FALSE.
1450 */
1451 bool
HasMember(const wxString & key) const1452 wxJSONValue::HasMember( const wxString& key ) const
1453 {
1454 bool r = false;
1455 wxJSONRefData* data = GetRefData();
1456 wxJSON_ASSERT( data );
1457
1458 if ( data && data->m_type == wxJSONTYPE_OBJECT ) {
1459 wxJSONInternalMap::iterator it = data->m_valMap.find( key );
1460 if ( it != data->m_valMap.end() ) {
1461 r = true;
1462 }
1463 }
1464 return r;
1465 }
1466
1467 //! Return the size of the array or map stored in this value.
1468 /*!
1469 Note that both the array and the key/value map may have a size of
1470 ZERO elements.
1471 If the stored value is not an array nor a key/value hashmap, the
1472 function returns -1.
1473 */
1474 int
Size() const1475 wxJSONValue::Size() const
1476 {
1477 wxJSONRefData* data = GetRefData();
1478 wxJSON_ASSERT( data );
1479
1480 int size = -1;
1481 if ( data->m_type == wxJSONTYPE_ARRAY ) {
1482 size = (int) data->m_valArray.GetCount();
1483 }
1484 if ( data->m_type == wxJSONTYPE_OBJECT ) {
1485 size = (int) data->m_valMap.size();
1486 }
1487 return size;
1488 }
1489
1490 //! Return the array of keys of this JSON object.
1491 /*!
1492 If the stored value is a key/value map, the function returns an
1493 array of strings containing the \e key of all elements.
1494 Note that the returned array may be empty if the map has ZERO
1495 elements.
1496 An empty string array is also returned if the stored value is
1497 not a key/value map.
1498 Also note that in debug builds, the function wxJSON_ASSERTs that the
1499 type of the stored object is wxJSONTYPE_OBJECT.
1500 */
1501 wxArrayString
GetMemberNames() const1502 wxJSONValue::GetMemberNames() const
1503 {
1504 wxJSONRefData* data = GetRefData();
1505 wxJSON_ASSERT( data );
1506 wxJSON_ASSERT( data->m_type == wxJSONTYPE_OBJECT );
1507
1508 wxArrayString arr;
1509 if ( data->m_type == wxJSONTYPE_OBJECT ) {
1510 wxJSONInternalMap::iterator it;
1511 for ( it = data->m_valMap.begin(); it != data->m_valMap.end(); it++ ) {
1512 arr.Add( it->first );
1513 }
1514 }
1515 return arr;
1516 }
1517
1518
1519 // appending items, resizing and deleting items
1520 // NOTE: these functions are not 'const' so we have to call
1521 // the COW() function before accessing data
1522
1523 //! Append the specified value in the array.
1524 /*!
1525 The function appends the value specified in the parameter to the array
1526 contained in this object.
1527 If this object does not contain an array type, the actual content is
1528 deleted, a new array type is created and the JSON value \c value is
1529 appended to the newly created array.
1530 Returns a reference to the appended object.
1531 */
1532 wxJSONValue&
Append(const wxJSONValue & value)1533 wxJSONValue::Append( const wxJSONValue& value )
1534 {
1535 wxJSONRefData* data = COW();
1536 wxJSON_ASSERT( data );
1537 if ( data->m_type != wxJSONTYPE_ARRAY ) {
1538 // we have to change the type of the actual object to the array type
1539 SetType( wxJSONTYPE_ARRAY );
1540 }
1541 // we add the wxJSONValue object to the wxObjArray: note that the
1542 // array makes a copy of the JSON-value object by calling its
1543 // copy ctor thus using reference count
1544 data->m_valArray.Add( value );
1545 wxJSONValue& v = data->m_valArray.Last();
1546 return v;
1547 }
1548
1549
1550 //! \overload Append( const wxJSONValue& )
1551 wxJSONValue&
Append(int i)1552 wxJSONValue::Append( int i )
1553 {
1554 wxJSONValue v( i );
1555 wxJSONValue& r = Append( v );
1556 return r;
1557 }
1558
1559 //! \overload Append( const wxJSONValue& )
1560 wxJSONValue&
Append(short int i)1561 wxJSONValue::Append( short int i )
1562 {
1563 wxJSONValue v( i );
1564 wxJSONValue& r = Append( v );
1565 return r;
1566 }
1567
1568 //! \overload Append( const wxJSONValue& )
1569 wxJSONValue&
Append(long int l)1570 wxJSONValue::Append( long int l )
1571 {
1572 wxJSONValue v( l );
1573 wxJSONValue& r = Append( v );
1574 return r;
1575 }
1576
1577 //! \overload Append( const wxJSONValue& )
1578 wxJSONValue&
Append(bool b)1579 wxJSONValue::Append( bool b )
1580 {
1581 wxJSONValue v( b );
1582 wxJSONValue& r = Append( v );
1583 return r;
1584 }
1585
1586 //! \overload Append( const wxJSONValue& )
1587 wxJSONValue&
Append(unsigned int ui)1588 wxJSONValue::Append( unsigned int ui )
1589 {
1590 wxJSONValue v( ui );
1591 wxJSONValue& r = Append( v );
1592 return r;
1593 }
1594
1595 //! \overload Append( const wxJSONValue& )
1596 wxJSONValue&
Append(unsigned short ui)1597 wxJSONValue::Append( unsigned short ui )
1598 {
1599 wxJSONValue v( ui );
1600 wxJSONValue& r = Append( v );
1601 return r;
1602 }
1603
1604 //! \overload Append( const wxJSONValue& )
1605 wxJSONValue&
Append(unsigned long ul)1606 wxJSONValue::Append( unsigned long ul )
1607 {
1608 wxJSONValue v( ul );
1609 wxJSONValue& r = Append( v );
1610 return r;
1611 }
1612
1613 //! \overload Append( const wxJSONValue& )
1614 wxJSONValue&
Append(double d)1615 wxJSONValue::Append( double d )
1616 {
1617 wxJSONValue v( d );
1618 wxJSONValue& r = Append( v );
1619 return r;
1620 }
1621
1622 //! \overload Append( const wxJSONValue& )
1623 wxJSONValue&
Append(const wxChar * str)1624 wxJSONValue::Append( const wxChar* str )
1625 {
1626 wxJSONValue v( str );
1627 wxJSONValue& r = Append( v );
1628 return r;
1629 }
1630
1631 //! \overload Append( const wxJSONValue& )
1632 wxJSONValue&
Append(const wxString & str)1633 wxJSONValue::Append( const wxString& str )
1634 {
1635 wxJSONValue v( str );
1636 wxJSONValue& r = Append( v );
1637 return r;
1638 }
1639
1640 //! \overload Append( const wxJSONValue& )
1641 wxJSONValue&
Append(const wxMemoryBuffer & buff)1642 wxJSONValue::Append( const wxMemoryBuffer& buff )
1643 {
1644 wxJSONValue v( buff );
1645 wxJSONValue& r = Append( v );
1646 return r;
1647 }
1648
1649 //! \overload Append( const wxJSONValue& )
1650 wxJSONValue&
Append(const void * buff,size_t len)1651 wxJSONValue::Append( const void* buff, size_t len )
1652 {
1653 wxJSONValue v( buff, len );
1654 wxJSONValue& r = Append( v );
1655 return r;
1656 }
1657
1658
1659 //! Concatenate a string to this string object.
1660 /*!
1661 The function concatenates \c str to the string contained
1662 in this object and returns TRUE if the operation is succefull.
1663 If the value stored in this value is not a string object
1664 the function does nothing and returns FALSE.
1665 Note that in order to be successfull, the value must contain
1666 a \b wxString object and not a pointer to C-string.
1667 */
1668 bool
Cat(const wxString & str)1669 wxJSONValue::Cat( const wxString& str )
1670 {
1671 wxJSONRefData* data = GetRefData();
1672 wxJSON_ASSERT( data );
1673
1674 bool r = false;
1675 if ( data->m_type == wxJSONTYPE_STRING ) {
1676 wxJSONRefData* data = COW();
1677 wxJSON_ASSERT( data );
1678 data->m_valString.append( str );
1679 r = true;
1680 }
1681 return r;
1682 }
1683
1684 //! Concatenate a memory buffer to this memory buffer object.
1685 /*!
1686 The function concatenates \c buff to the \b wxMemoryBuffer object contained
1687 in this object and returns TRUE if the operation is succefull.
1688 If the value stored in this value is not a memory buffer object
1689 the function does nothing and returns FALSE.
1690 */
1691 bool
Cat(const wxMemoryBuffer & buff)1692 wxJSONValue::Cat( const wxMemoryBuffer& buff )
1693 {
1694 wxJSONRefData* data = GetRefData();
1695 wxJSON_ASSERT( data );
1696
1697 bool r = false;
1698 if ( data->m_type == wxJSONTYPE_MEMORYBUFF ) {
1699 wxJSONRefData* data = COW();
1700 wxJSON_ASSERT( data );
1701 data->m_memBuff->AppendData( buff.GetData(), buff.GetDataLen());
1702 r = true;
1703 }
1704 return r;
1705 }
1706
1707
1708 //! \overload Cat( const wxString& )
1709 bool
Cat(const wxChar * str)1710 wxJSONValue::Cat( const wxChar* str )
1711 {
1712 wxJSONRefData* data = GetRefData();
1713 wxJSON_ASSERT( data );
1714
1715 bool r = false;
1716 if ( data->m_type == wxJSONTYPE_STRING ) {
1717 wxJSONRefData* data = COW();
1718 wxJSON_ASSERT( data );
1719 data->m_valString.append( str );
1720 r = true;
1721 }
1722 return r;
1723 }
1724
1725
1726 //! Remove the item at the specified index or key.
1727 /*!
1728 The function removes the item at index \c index or at the specified
1729 key in the array or map.
1730 If this object does not contain an array (for a index parameter) or a map
1731 (for a key parameter), the function does nothing and returns FALSE.
1732 If the element does not exist, FALSE is returned.
1733 */
1734 bool
Remove(int index)1735 wxJSONValue::Remove( int index )
1736 {
1737 wxJSONRefData* data = COW();
1738 wxJSON_ASSERT( data );
1739
1740 bool r = false;
1741 if ( data->m_type == wxJSONTYPE_ARRAY ) {
1742 data->m_valArray.RemoveAt( index );
1743 r = true;
1744 }
1745 return r;
1746 }
1747
1748
1749 //! \overload Remove( int )
1750 bool
Remove(const wxString & key)1751 wxJSONValue::Remove( const wxString& key )
1752 {
1753 wxJSONRefData* data = COW();
1754 wxJSON_ASSERT( data );
1755
1756 bool r = false;
1757 if ( data->m_type == wxJSONTYPE_OBJECT ) {
1758 wxJSONInternalMap::size_type count = data->m_valMap.erase( key );
1759 if ( count > 0 ) {
1760 r = true;
1761 }
1762 }
1763 return r;
1764 }
1765
1766
1767 //! Clear the object value.
1768 /*!
1769 This function causes the object to be empty.
1770 The function simply calls UnRef() making this object to become
1771 invalid and set its type to wxJSONTYPE_INVALID.
1772 */
1773 void
Clear()1774 wxJSONValue::Clear()
1775 {
1776 UnRef();
1777 SetType( wxJSONTYPE_INVALID );
1778 }
1779
1780 // retrieve an item
1781
1782 //! Return the item at the specified index.
1783 /*!
1784 The function returns a reference to the object at the specified
1785 index.
1786 If the element does not exist, the array is enlarged to \c index + 1
1787 elements and a reference to the last element will be returned.
1788 New elements will contain NULL values.
1789 If this object does not contain an array, the old value is
1790 replaced by an array object which will be enlarged to the needed
1791 dimension.
1792 */
1793 wxJSONValue&
Item(unsigned index)1794 wxJSONValue::Item( unsigned index )
1795 {
1796 wxJSONRefData* data = COW();
1797 wxJSON_ASSERT( data );
1798
1799 if ( data->m_type != wxJSONTYPE_ARRAY ) {
1800 data = SetType( wxJSONTYPE_ARRAY );
1801 }
1802 int size = Size();
1803 wxJSON_ASSERT( size >= 0 );
1804 // if the desired element does not yet exist, we create as many
1805 // elements as needed; the new values will be 'null' values
1806 if ( index >= (unsigned) size ) {
1807 wxJSONValue v( wxJSONTYPE_NULL);
1808 int missing = index - size + 1;
1809 data->m_valArray.Add( v, missing );
1810 }
1811 return data->m_valArray.Item( index );
1812 }
1813
1814 //! Return the item at the specified key.
1815 /*!
1816 The function returns a reference to the object in the map
1817 that has the specified key.
1818 If \c key does not exist, a new NULL value is created with
1819 the provided key and a reference to it is returned.
1820 If this object does not contain a map, the old value is
1821 replaced by a map object.
1822 */
1823 wxJSONValue&
Item(const wxString & key)1824 wxJSONValue::Item( const wxString& key )
1825 {
1826 wxLogTrace( traceMask, _T("(%s) searched key=\'%s\'"), __PRETTY_FUNCTION__, key.c_str());
1827 #if !wxCHECK_VERSION(2,9,0)
1828 wxLogTrace( traceMask, _T("(%s) actual object: %s"), __PRETTY_FUNCTION__, GetInfo().c_str());
1829 #endif
1830
1831 wxJSONRefData* data = COW();
1832 wxJSON_ASSERT( data );
1833
1834 if ( data->m_type != wxJSONTYPE_OBJECT ) {
1835 // deletes the contained value;
1836 data = SetType( wxJSONTYPE_OBJECT );
1837 return data->m_valMap[key];
1838 }
1839 wxLogTrace( traceMask, _T("(%s) searching key \'%s' in the actual object"),
1840 __PRETTY_FUNCTION__, key.c_str() );
1841 return data->m_valMap[key];
1842 }
1843
1844
1845 //! Return the item at the specified index.
1846 /*!
1847 The function returns a copy of the object at the specified
1848 index.
1849 If the element does not exist, the function returns an \b invalid value.
1850 */
1851 wxJSONValue
ItemAt(unsigned index) const1852 wxJSONValue::ItemAt( unsigned index ) const
1853 {
1854 wxJSONRefData* data = GetRefData();
1855 wxJSON_ASSERT( data );
1856
1857 wxJSONValue v( wxJSONTYPE_INVALID );
1858 if ( data->m_type == wxJSONTYPE_ARRAY ) {
1859 int size = Size();
1860 wxJSON_ASSERT( size >= 0 );
1861 if ( index < (unsigned) size ) {
1862 v = data->m_valArray.Item( index );
1863 }
1864 }
1865 return v;
1866 }
1867
1868 //! Return the item at the specified key.
1869 /*!
1870 The function returns a copy of the object in the map
1871 that has the specified key.
1872 If \c key does not exist, an \b invalid value is returned.
1873 */
1874 wxJSONValue
ItemAt(const wxString & key) const1875 wxJSONValue::ItemAt( const wxString& key ) const
1876 {
1877 wxLogTrace( traceMask, _T("(%s) searched key=\'%s\'"), __PRETTY_FUNCTION__, key.c_str());
1878 #ifndef __WXOSX__
1879 wxLogTrace( traceMask, _T("(%s) actual object: %s"), __PRETTY_FUNCTION__, GetInfo().c_str());
1880 #endif
1881
1882 wxJSONRefData* data = GetRefData();
1883 wxJSON_ASSERT( data );
1884
1885 wxJSONValue v( wxJSONTYPE_INVALID );
1886 if ( data->m_type == wxJSONTYPE_OBJECT ) {
1887 wxJSONInternalMap::const_iterator it = data->m_valMap.find( key );
1888 if ( it != data->m_valMap.end() ) {
1889 v = it->second;
1890 }
1891 }
1892 return v;
1893 }
1894
1895
1896 //! Return the item at the specified index.
1897 /*!
1898 The function returns a reference to the object at the specified
1899 index.
1900 If the element does not exist, the array is enlarged to \c index + 1
1901 elements and a reference to the last element will be returned.
1902 New elements will contain NULL values.
1903 If this object does not contain an array, the old value is
1904 replaced by an array object.
1905 */
1906 wxJSONValue&
operator [](unsigned index)1907 wxJSONValue::operator [] ( unsigned index )
1908 {
1909 wxJSONValue& v = Item( index );
1910 return v;
1911 }
1912
1913 //! Return the item at the specified key.
1914 /*!
1915 The function returns a reference to the object in the map
1916 that has the specified key.
1917 If \c key does not exist, a new NULL value is created with
1918 the provided key and a reference to it is returned.
1919 If this object does not contain a map, the old value is
1920 replaced by a map object.
1921 */
1922 wxJSONValue&
operator [](const wxString & key)1923 wxJSONValue::operator [] ( const wxString& key )
1924 {
1925 wxJSONValue& v = Item( key );
1926 return v;
1927 }
1928
1929 //
1930 // assignment operators
1931 // note that reference counting is only used if the original
1932 // value is a wxJSONValue object
1933 // in all other cases, the operator= function deletes the old
1934 // content and assigns the new one
1935
1936
1937 //! Assign the specified value to this object replacing the old value.
1938 /*!
1939 The assignment operator assigns to this object the value specified in the
1940 right operand of the assignment operator.
1941 Note that the old value is deleted but not the other data members
1942 in the wxJSONRefData structure.
1943 This is particularly usefull for the parser class which stores
1944 comment lines in a temporary wxJSONvalue object that is of type
1945 wxJSONTYPE_INVALID.
1946 As comment lines may apear before the value they refer to, comments
1947 are stored in a value that is not yet being read.
1948 when the value is read, it is assigned to the temporary JSON value
1949 object without deleting the comment lines.
1950 */
1951 wxJSONValue&
operator =(int i)1952 wxJSONValue::operator = ( int i )
1953 {
1954 wxJSONRefData* data = SetType( wxJSONTYPE_INT );
1955 data->m_value.VAL_INT = i;
1956 return *this;
1957 }
1958
1959
1960 //! \overload operator = (int)
1961 wxJSONValue&
operator =(bool b)1962 wxJSONValue::operator = ( bool b )
1963 {
1964 wxJSONRefData* data = SetType( wxJSONTYPE_BOOL );
1965 data->m_value.m_valBool = b;
1966 return *this;
1967 }
1968
1969 //! \overload operator = (int)
1970 wxJSONValue&
operator =(unsigned int ui)1971 wxJSONValue::operator = ( unsigned int ui )
1972 {
1973 wxJSONRefData* data = SetType( wxJSONTYPE_UINT );
1974 data->m_value.VAL_UINT = ui;
1975 return *this;
1976 }
1977
1978 //! \overload operator = (int)
1979 wxJSONValue&
operator =(long l)1980 wxJSONValue::operator = ( long l )
1981 {
1982 wxJSONRefData* data = SetType( wxJSONTYPE_INT );
1983 data->m_value.VAL_INT = l;
1984 return *this;
1985 }
1986
1987 //! \overload operator = (int)
1988 wxJSONValue&
operator =(unsigned long ul)1989 wxJSONValue::operator = ( unsigned long ul )
1990 {
1991 wxJSONRefData* data = SetType( wxJSONTYPE_UINT );
1992 data->m_value.VAL_UINT = ul;
1993 return *this;
1994 }
1995
1996
1997 //! \overload operator = (int)
1998 wxJSONValue&
operator =(short i)1999 wxJSONValue::operator = ( short i )
2000 {
2001 wxJSONRefData* data = SetType( wxJSONTYPE_INT );
2002 data->m_value.VAL_INT = i;
2003 return *this;
2004 }
2005
2006
2007 //! \overload operator = (int)
2008 wxJSONValue&
operator =(unsigned short ui)2009 wxJSONValue::operator = ( unsigned short ui )
2010 {
2011 wxJSONRefData* data = SetType( wxJSONTYPE_UINT );
2012 data->m_value.VAL_UINT = ui;
2013 return *this;
2014 }
2015
2016 //! \overload operator = (int)
2017 wxJSONValue&
operator =(double d)2018 wxJSONValue::operator = ( double d )
2019 {
2020 wxJSONRefData* data = SetType( wxJSONTYPE_DOUBLE );
2021 data->m_value.m_valDouble = d;
2022 return *this;
2023 }
2024
2025
2026 //! \overload operator = (int)
2027 wxJSONValue&
operator =(const wxChar * str)2028 wxJSONValue::operator = ( const wxChar* str )
2029 {
2030 wxJSONRefData* data = SetType( wxJSONTYPE_CSTRING );
2031 data->m_value.m_valCString = str;
2032 #if !defined( WXJSON_USE_CSTRING )
2033 data->m_type = wxJSONTYPE_STRING;
2034 data->m_valString.assign( str );
2035 #endif
2036 return *this;
2037 }
2038
2039 //! \overload operator = (int)
2040 wxJSONValue&
operator =(const wxString & str)2041 wxJSONValue::operator = ( const wxString& str )
2042 {
2043 wxJSONRefData* data = SetType( wxJSONTYPE_STRING );
2044 data->m_valString.assign( str );
2045 return *this;
2046 }
2047
2048
2049 //! Assigns to this object a memory buffer type
2050 /*!
2051 As with the ctor, this function makes a deep copy of the
2052 memory buffer \c buff so changes made to the original buffer
2053 does not reflect to the memory buffer stored in this JSON value.
2054 */
2055 wxJSONValue&
operator =(const wxMemoryBuffer & buff)2056 wxJSONValue::operator = ( const wxMemoryBuffer& buff )
2057 {
2058 wxJSONRefData* data = SetType( wxJSONTYPE_MEMORYBUFF );
2059 data->m_memBuff = new wxMemoryBuffer();
2060 const void* ptr = buff.GetData();
2061 size_t len = buff.GetDataLen();
2062 if ( data->m_memBuff && len ) {
2063 data->m_memBuff->AppendData( ptr, len );
2064 }
2065 return *this;
2066 }
2067
2068
2069 //! Assignment operator using reference counting.
2070 /*!
2071 Unlike all other assignment operators, this one makes a
2072 swallow copy of the other JSON value object.
2073 The function calls \c Ref() to get a shared referenced
2074 data.
2075 \sa \ref json_internals_cow
2076 */
2077 wxJSONValue&
operator =(const wxJSONValue & other)2078 wxJSONValue::operator = ( const wxJSONValue& other )
2079 {
2080 Ref( other );
2081 return *this;
2082 }
2083
2084
2085 // finding elements
2086
2087
2088 //! Return a value or a default value.
2089 /*!
2090 This function returns a copy of the value object for the specified key.
2091 If the key is not found, a copy of \c defaultValue is returned.
2092 Note that the returned values are not real copy of the \c key or the
2093 default values because \e copy-on-write is used by this class.
2094 However, you have to treat them as real copies; in other words, if you
2095 change the values of the returned object your changes does not reflect
2096 in the otiginal value.
2097 Example:
2098 \code
2099 wxJSONValue defaultValue( 0 );
2100 wxJSONvalue v1;
2101 v1["key"] = 100; // 'v1["key"]' contains the integer 100
2102
2103 // 'v2' contains 100 but it is a swallow copy of 'v1["key"]'
2104 wxJSONValue v2 = v1.Get( "key", defaultValue );
2105
2106 // 'v1["key"]' still contains 100
2107 v2 = 200;
2108
2109 // if you want your change to be reflected in the 'v1' object
2110 // you have to assign it
2111 v1["key"] = v2;
2112 \endcode
2113 */
2114 wxJSONValue
Get(const wxString & key,const wxJSONValue & defaultValue) const2115 wxJSONValue::Get( const wxString& key, const wxJSONValue& defaultValue ) const
2116 {
2117 // NOTE: this function does many wxJSONValue copies.
2118 // so implementing COW is a good thing
2119
2120 // this is the first copy (the default value)
2121 wxJSONValue v( defaultValue );
2122
2123 wxJSONRefData* data = GetRefData();
2124 wxJSON_ASSERT( data );
2125 if ( data->m_type == wxJSONTYPE_OBJECT ) {
2126 wxJSONInternalMap::iterator it = data->m_valMap.find( key );
2127 if ( it != data->m_valMap.end() ) {
2128 v = it->second;
2129 }
2130 }
2131 return v;
2132 }
2133
2134
2135 // protected functions
2136
2137 //! Find an element
2138 /*!
2139 The function returns a pointer to the element at index \c index
2140 or a NULL pointer if \c index does not exist.
2141 A NULL pointer is also returned if the object does not contain an
2142 array nor a key/value map.
2143 */
2144 wxJSONValue*
Find(unsigned index) const2145 wxJSONValue::Find( unsigned index ) const
2146 {
2147 wxJSONRefData* data = GetRefData();
2148 wxJSON_ASSERT( data );
2149
2150 wxJSONValue* vp = 0;
2151
2152 if ( data->m_type == wxJSONTYPE_ARRAY ) {
2153 size_t size = data->m_valArray.GetCount();
2154 if ( index < size ) {
2155 vp = &(data->m_valArray.Item( index ));
2156 }
2157 }
2158 return vp;
2159 }
2160
2161 //! Find an element
2162 /*!
2163 The function returns a pointer to the element with key \c key
2164 or a NULL pointer if \c key does not exist.
2165 A NULL pointer is also returned if the object does not contain a
2166 key/value map.
2167 */
2168 wxJSONValue*
Find(const wxString & key) const2169 wxJSONValue::Find( const wxString& key ) const
2170 {
2171 wxJSONRefData* data = GetRefData();
2172 wxJSON_ASSERT( data );
2173
2174 wxJSONValue* vp = 0;
2175
2176 if ( data->m_type == wxJSONTYPE_OBJECT ) {
2177 wxJSONInternalMap::iterator it = data->m_valMap.find( key );
2178 if ( it != data->m_valMap.end() ) {
2179 vp = &(it->second);
2180 }
2181 }
2182 return vp;
2183 }
2184
2185
2186
2187 //! Return a string description of the type
2188 /*!
2189 This static function is only usefull for debugging purposes and
2190 should not be used by users of this class.
2191 It simply returns a string representation of the JSON value
2192 type stored in a object.
2193 For example, if \c type is wxJSONTYPE_INT the function returns the
2194 string "wxJSONTYPE_INT".
2195 If \c type is out of range, an empty string is returned (should
2196 never happen).
2197 */
2198 wxString
TypeToString(wxJSONType type)2199 wxJSONValue::TypeToString( wxJSONType type )
2200 {
2201 static const wxChar* str[] = {
2202 _T( "wxJSONTYPE_INVALID" ), // 0
2203 _T( "wxJSONTYPE_NULL" ), // 1
2204 _T( "wxJSONTYPE_INT" ), // 2
2205 _T( "wxJSONTYPE_UINT" ), // 3
2206 _T( "wxJSONTYPE_DOUBLE" ), // 4
2207 _T( "wxJSONTYPE_STRING" ), // 5
2208 _T( "wxJSONTYPE_CSTRING" ), // 6
2209 _T( "wxJSONTYPE_BOOL" ), // 7
2210 _T( "wxJSONTYPE_ARRAY" ), // 8
2211 _T( "wxJSONTYPE_OBJECT" ), // 9
2212 _T( "wxJSONTYPE_LONG" ), // 10
2213 _T( "wxJSONTYPE_INT64" ), // 11
2214 _T( "wxJSONTYPE_ULONG" ), // 12
2215 _T( "wxJSONTYPE_UINT64" ), // 13
2216 _T( "wxJSONTYPE_SHORT" ), // 14
2217 _T( "wxJSONTYPE_USHORT" ), // 15
2218 _T( "wxJSONTYPE_MEMORYBUFF" ), // 16
2219 };
2220
2221 wxString s;
2222 int idx = (int) type;
2223 if ( idx >= 0 && idx < 17 ) {
2224 s = str[idx];
2225 }
2226 return s;
2227 }
2228
2229 //! Returns informations about the object
2230 /*!
2231 The function is only usefull for debugging purposes and will probably
2232 be dropped in future versions.
2233 Returns a string that contains info about the object such as:
2234
2235 \li the type of the object
2236 \li the size
2237 \li the progressive counter
2238 \li the pointer to referenced data
2239 \li the progressive counter of referenced data
2240 \li the number of share of referenced data
2241
2242 The \c deep parameter is used to specify if the function will be called
2243 recursively in order to dump sub-items. If the parameter is TRUE than a
2244 deep dump is executed.
2245
2246 The \c indent is the initial indentation: it is incremented by 3 every
2247 time the Dump() function is called recursively.
2248 */
2249 wxString
Dump(bool deep,int indent) const2250 wxJSONValue::Dump( bool deep, int indent ) const
2251 {
2252 wxJSONRefData* data = GetRefData();
2253 wxJSON_ASSERT( data );
2254
2255 wxJSONType type = GetType();
2256
2257 wxString s;
2258 if ( indent > 0 ) {
2259 s.append( indent, ' ' );
2260 }
2261
2262 wxString s1;
2263 wxString s2;
2264 #if defined( WXJSON_USE_VALUE_COUNTER )
2265 s1.Printf( _T("Object: Progr=%d Type=%s Size=%d comments=%d\n"),
2266 m_progr,
2267 TypeToString( type ).c_str(),
2268 Size(),
2269 data->m_comments.GetCount() );
2270 s2.Printf(_T(" : RefData=%p Progr=%d Num shares=%d\n"),
2271 data, data->m_progr, data->GetRefCount() );
2272 #else
2273 s1.Printf( _T("Object: Type=%s Size=%d comments=%d\n"),
2274 TypeToString( type ).c_str(),
2275 Size(),
2276 data->m_comments.GetCount() );
2277 s2.Printf(_T(" : RefData=%p Num shares=%d\n"),
2278 data, data->GetRefCount() );
2279 #endif
2280 s.append( s1 );
2281 if ( indent > 0 ) {
2282 s.append( indent, ' ' );
2283 }
2284 s.append( s2 );
2285
2286 wxString sub;
2287
2288 // if we have to do a deep dump, we call the Dump() function for
2289 // every sub-item
2290 if ( deep ) {
2291 indent += 3;
2292 const wxJSONInternalMap* map;
2293 int size;;
2294 wxJSONInternalMap::const_iterator it;
2295 switch ( type ) {
2296 case wxJSONTYPE_OBJECT :
2297 map = AsMap();
2298 size = Size();
2299 for ( it = map->begin(); it != map->end(); ++it ) {
2300 const wxJSONValue& v = it->second;
2301 sub = v.Dump( true, indent );
2302 s.append( sub );
2303 }
2304 break;
2305 case wxJSONTYPE_ARRAY :
2306 size = Size();
2307 for ( int i = 0; i < size; i++ ) {
2308 const wxJSONValue* v = Find( i );
2309 wxJSON_ASSERT( v );
2310 sub = v->Dump( true, indent );
2311 s.append( sub );
2312 }
2313 break;
2314 default :
2315 break;
2316 }
2317 }
2318 return s;
2319 }
2320
2321 //! Returns informations about the object
2322 /*!
2323 The function is only usefull for debugging purposes and will probably
2324 be dropped in future versions.
2325 You should not rely on this function to exist in future versions.
2326 */
2327 wxString
GetInfo() const2328 wxJSONValue::GetInfo() const
2329 {
2330 wxJSONRefData* data = GetRefData();
2331 wxJSON_ASSERT( data );
2332
2333 wxString s;
2334 #if defined( WXJSON_USE_VALUE_CONTER )
2335 s.Printf( _T("Object: Progr=%d Type=%s Size=%d comments=%d\n"),
2336 data->m_progr,
2337 wxJSONValue::TypeToString( data->m_type ).c_str(),
2338 Size(),
2339 data->m_comments.GetCount() );
2340 #else
2341 s.Printf( _T("Object: Type=%s Size=%d comments=%d\n"),
2342 wxJSONValue::TypeToString( data->m_type ).c_str(),
2343 Size(), data->m_comments.GetCount() );
2344 #endif
2345 if ( data->m_type == wxJSONTYPE_OBJECT ) {
2346 wxArrayString arr = GetMemberNames();
2347 for ( unsigned int i = 0; i < arr.size(); i++ ) {
2348 s.append( _T(" Member name: "));
2349 s.append( arr[i] );
2350 s.append( _T("\n") );
2351 }
2352 }
2353 return s;
2354 }
2355
2356 //! The comparison function
2357 /*!
2358 This function returns TRUE if this object looks like \c other.
2359 Note that this class does not define a comparison operator
2360 (the classical \b operator== function) because the notion
2361 of \b equal for JSON values objects is not applicable.
2362 The comment strings array are not compared: JSON value objects
2363 are \b the \b same if they contains the same values, regardless the
2364 comment's strings.
2365
2366 Note that the function does not return the element that cause the
2367 comparison to return FALSE. There is not a good structure to
2368 tell this information.
2369 If you need it for debugging purposes, you have to turn on the
2370 \b sameas tracing feature by setting the WXTRACE environment
2371 variable (you need a debug version of the application):
2372
2373 \code
2374 export WXTRACE=sameas // for unix systems that use bash
2375 \endcode
2376
2377 Note that if the two JSON value objects share the same referenced
2378 data, the function immediatly returns TRUE without doing a deep
2379 comparison which is, sure, useless.
2380 For further info see \ref json_internals_compare.
2381 */
2382 bool
IsSameAs(const wxJSONValue & other) const2383 wxJSONValue::IsSameAs( const wxJSONValue& other ) const
2384 {
2385 // this is a recursive function: it calls itself
2386 // for every 'value' object in an array or map
2387 bool r = false;
2388
2389 // some variables used in the switch statement
2390 int size;
2391 wxJSONInternalMap::const_iterator it;
2392
2393 // get the referenced data for the two objects
2394 wxJSONRefData* data = GetRefData();
2395 wxJSONRefData* otherData = other.GetRefData();
2396
2397 if ( data == otherData ) {
2398 wxLogTrace( compareTraceMask, _T("(%s) objects share the same referenced data - r=TRUE"),
2399 __PRETTY_FUNCTION__ );
2400 return true;
2401 }
2402
2403
2404 // if the type does not match the function compares the values if
2405 // they are of compatible types such as INT, UINT and DOUBLE
2406 if ( data->m_type != otherData->m_type ) {
2407 // if the types are not compatible, returns false
2408 // otherwise compares the compatible types: INT, UINT and DOUBLE
2409 double val;
2410 switch ( data->m_type ) {
2411 case wxJSONTYPE_INT :
2412 if ( otherData->m_type == wxJSONTYPE_UINT ) {
2413 // compare the bits and returns true if value is between 0 and LLONG_MAX
2414 if ( (data->m_value.VAL_UINT <= LLONG_MAX ) &&
2415 (data->m_value.VAL_UINT == otherData->m_value.VAL_UINT))
2416 {
2417 r = true;
2418 }
2419 }
2420 else if ( otherData->m_type == wxJSONTYPE_DOUBLE ) {
2421 val = data->m_value.VAL_INT;
2422 if ( val == otherData->m_value.m_valDouble ) {
2423 r = true;
2424 }
2425 }
2426 else {
2427 r = false;
2428 }
2429 break;
2430 case wxJSONTYPE_UINT :
2431 if ( otherData->m_type == wxJSONTYPE_INT ) {
2432 // compare the bits and returns true if value is between 0 and LLONG_MAX
2433 if ( (data->m_value.VAL_UINT <= LLONG_MAX ) &&
2434 (data->m_value.VAL_UINT == otherData->m_value.VAL_UINT))
2435 {
2436 r = true;
2437 }
2438 }
2439 else if ( otherData->m_type == wxJSONTYPE_DOUBLE ) {
2440 val = data->m_value.VAL_UINT;
2441 if ( val == otherData->m_value.m_valDouble ) {
2442 r = true;
2443 }
2444 }
2445 else {
2446 r = false;
2447 }
2448 break;
2449 case wxJSONTYPE_DOUBLE :
2450 if ( otherData->m_type == wxJSONTYPE_INT ) {
2451 val = otherData->m_value.VAL_INT;
2452 if ( val == data->m_value.m_valDouble ) {
2453 r = true;
2454 }
2455 }
2456 else if ( otherData->m_type == wxJSONTYPE_UINT ) {
2457 val = otherData->m_value.VAL_UINT;
2458 if ( val == data->m_value.m_valDouble ) {
2459 r = true;
2460 }
2461 }
2462 else {
2463 r = false;
2464 }
2465 break;
2466 default:
2467 r = false;
2468 break;
2469 }
2470 return r;
2471 }
2472
2473 // the two objects have the same 'm_type'
2474
2475 // for comparing wxJSONTYPE_CSTRING we use two temporary wxString
2476 // objects: this is to avoid using strcmp() and wcscmp() which
2477 // may not be available on all platforms
2478 wxString s1, s2;
2479 r = true;
2480 int r1;
2481
2482 switch ( data->m_type ) {
2483 case wxJSONTYPE_INVALID :
2484 case wxJSONTYPE_NULL :
2485 // there is no need to compare the values
2486 break;
2487 case wxJSONTYPE_INT :
2488 if ( data->m_value.VAL_INT != otherData->m_value.VAL_INT ) {
2489 r = false;
2490 }
2491 break;
2492 case wxJSONTYPE_UINT :
2493 if ( data->m_value.VAL_UINT != otherData->m_value.VAL_UINT ) {
2494 r = false;
2495 }
2496 break;
2497 case wxJSONTYPE_DOUBLE :
2498 if ( data->m_value.m_valDouble != otherData->m_value.m_valDouble ) {
2499 r = false;
2500 }
2501 break;
2502 case wxJSONTYPE_CSTRING :
2503 s1 = wxString( data->m_value.m_valCString );
2504 s2 = wxString( otherData->m_value.m_valCString );
2505 if ( s1 != s2 ) {
2506 r = false;
2507 }
2508 break;
2509 case wxJSONTYPE_BOOL :
2510 if ( data->m_value.m_valBool != otherData->m_value.m_valBool ) {
2511 r = false;
2512 }
2513 break;
2514 case wxJSONTYPE_STRING :
2515 if ( data->m_valString != otherData->m_valString ) {
2516 r = false;
2517 }
2518 break;
2519 case wxJSONTYPE_MEMORYBUFF :
2520 // we cannot simply use the operator ==; we need a deep comparison
2521 r1 = CompareMemoryBuff( *(data->m_memBuff), *(otherData->m_memBuff));
2522 if ( r1 != 0 ) {
2523 r = false;
2524 }
2525 break;
2526 case wxJSONTYPE_ARRAY :
2527 size = Size();
2528 wxLogTrace( compareTraceMask, _T("(%s) Comparing an array object - size=%d"),
2529 __PRETTY_FUNCTION__, size );
2530
2531 if ( size != other.Size() ) {
2532 wxLogTrace( compareTraceMask, _T("(%s) Sizes does not match"),
2533 __PRETTY_FUNCTION__ );
2534 return false;
2535 }
2536 // compares every element in this object with the element of
2537 // the same index in the 'other' object
2538 for ( int i = 0; i < size; i++ ) {
2539 wxLogTrace( compareTraceMask, _T("(%s) Comparing array element=%d"),
2540 __PRETTY_FUNCTION__, i );
2541 wxJSONValue v1 = ItemAt( i );
2542 wxJSONValue v2 = other.ItemAt( i );
2543
2544 if ( !v1.IsSameAs( v2 )) {
2545 return false;
2546 }
2547 }
2548 break;
2549 case wxJSONTYPE_OBJECT :
2550 size = Size();
2551 wxLogTrace( compareTraceMask, _T("(%s) Comparing a map obejct - size=%d"),
2552 __PRETTY_FUNCTION__, size );
2553
2554 if ( size != other.Size() ) {
2555 wxLogTrace( compareTraceMask, _T("(%s) Comparison failed - sizes does not match"),
2556 __PRETTY_FUNCTION__ );
2557 return false;
2558 }
2559 // for every key calls itself on the value found in
2560 // the other object. if 'key' does no exist, returns FALSE
2561 for ( it = data->m_valMap.begin(); it != data->m_valMap.end(); it++ ) {
2562 wxString key = it->first;
2563 wxLogTrace( compareTraceMask, _T("(%s) Comparing map object - key=%s"),
2564 __PRETTY_FUNCTION__, key.c_str() );
2565 wxJSONValue otherVal = other.ItemAt( key );
2566 bool isSame = it->second.IsSameAs( otherVal );
2567 if ( !isSame ) {
2568 wxLogTrace( compareTraceMask, _T("(%s) Comparison failed for the last object"),
2569 __PRETTY_FUNCTION__ );
2570 return false;
2571 }
2572 }
2573 break;
2574 default :
2575 // should never happen
2576 wxFAIL_MSG( _T("wxJSONValue::IsSameAs() unexpected wxJSONType"));
2577 break;
2578 }
2579 return r;
2580 }
2581
2582 //! Add a comment to this JSON value object.
2583 /*!
2584 The function adds a comment string to this JSON value object and returns
2585 the total number of comment strings belonging to this value.
2586 Note that the comment string must be a valid C/C++ comment because the
2587 wxJSONWriter does not modify it.
2588 In other words, a C++ comment string must start with '//' and must end with
2589 a new-line character. If the final LF char is missing, the
2590 automatically adds it.
2591 You can also add C-style comments which must be enclosed in the usual
2592 C-comment characters.
2593 For C-style comments, the function does not try to append the final comment
2594 characters but allows trailing whitespaces and new-line chars.
2595 The \c position parameter is one of:
2596
2597 \li wxJSONVALUE_COMMENT_BEFORE: the comment will be written before the value
2598 \li wxJSONVALUE_COMMENT_INLINE: the comment will be written on the same line
2599 \li wxJSONVALUE_COMMENT_AFTER: the comment will be written after the value
2600 \li wxJSONVALUE_COMMENT_DEFAULT: the old value of comment's position is not
2601 changed; if no comments were added to the value object this is the
2602 same as wxJSONVALUE_COMMENT_BEFORE.
2603
2604 To know more about comment's storage see \ref json_comment_add
2605
2606 */
2607 int
AddComment(const wxString & str,int position)2608 wxJSONValue::AddComment( const wxString& str, int position )
2609 {
2610 wxJSONRefData* data = COW();
2611 wxJSON_ASSERT( data );
2612
2613 wxLogTrace( traceMask, _T("(%s) comment=%s"), __PRETTY_FUNCTION__, str.c_str() );
2614 int r = -1;
2615 int len = str.length();
2616 if ( len < 2 ) {
2617 wxLogTrace( traceMask, _T(" error: len < 2") );
2618 return -1;
2619 }
2620 if ( str[0] != '/' ) {
2621 wxLogTrace( traceMask, _T(" error: does not start with\'/\'") );
2622 return -1;
2623 }
2624 if ( str[1] == '/' ) { // a C++ comment: check that it ends with '\n'
2625 wxLogTrace( traceMask, _T(" C++ comment" ));
2626 if ( str.GetChar(len - 1) != '\n' ) {
2627 wxString temp( str );
2628 temp.append( 1, '\n' );
2629 data->m_comments.Add( temp );
2630 wxLogTrace( traceMask, _T(" C++ comment: LF added") );
2631 }
2632 else {
2633 data->m_comments.Add( str );
2634 }
2635 r = data->m_comments.size();
2636 }
2637 else if ( str[1] == '*' ) { // a C-style comment: check that it ends with '*/'
2638 wxLogTrace( traceMask, _T(" C-style comment") );
2639 int lastPos = len - 1;
2640 wxChar ch = str.GetChar( lastPos );
2641 // skip leading whitespaces
2642 while ( ch == ' ' || ch == '\n' || ch == '\t' ) {
2643 --lastPos;
2644 ch = str.GetChar( lastPos );
2645 }
2646 if ( str.GetChar( lastPos ) == '/' && str.GetChar( lastPos - 1 ) == '*' ) {
2647 data->m_comments.Add( str );
2648 r = data->m_comments.size();
2649 }
2650 }
2651 else {
2652 wxLogTrace( traceMask, _T(" error: is not a valid comment string") );
2653 r = -1;
2654 }
2655 // if the comment was stored, store the position
2656 if ( r >= 0 && position != wxJSONVALUE_COMMENT_DEFAULT ) {
2657 data->m_commentPos = position;
2658 }
2659 return r;
2660 }
2661
2662 //! Add one or more comments to this JSON value object.
2663 /*!
2664 The function adds the strings contained in \c comments to the comment's
2665 string array of this value object by calling the AddComment( const wxString&,int)
2666 function for every string in the \c comment array.
2667 Returns the number of strings correctly added.
2668 */
2669 int
AddComment(const wxArrayString & comments,int position)2670 wxJSONValue::AddComment( const wxArrayString& comments, int position )
2671 {
2672 int siz = comments.GetCount(); int r = 0;
2673 for ( int i = 0; i < siz; i++ ) {
2674 int r2 = AddComment( comments[i], position );
2675 if ( r2 >= 0 ) {
2676 ++r;
2677 }
2678 }
2679 return r;
2680 }
2681
2682 //! Return a comment string.
2683 /*!
2684 The function returns the comment string at index \c idx.
2685 If \c idx is out of range, an empty string is returned.
2686 If \c idx is equal to -1, then the function returns a string
2687 that contains all comment's strings stored in the array.
2688 */
2689 wxString
GetComment(int idx) const2690 wxJSONValue::GetComment( int idx ) const
2691 {
2692 wxJSONRefData* data = GetRefData();
2693 wxJSON_ASSERT( data );
2694
2695 wxString s;
2696 int size = data->m_comments.GetCount();
2697 if ( idx < 0 ) {
2698 for ( int i = 0; i < size; i++ ) {
2699 s.append( data->m_comments[i] );
2700 }
2701 }
2702 else if ( idx < size ) {
2703 s = data->m_comments[idx];
2704 }
2705 return s;
2706 }
2707
2708 //! Return the number of comment strings.
2709 int
GetCommentCount() const2710 wxJSONValue::GetCommentCount() const
2711 {
2712 wxJSONRefData* data = GetRefData();
2713 wxJSON_ASSERT( data );
2714
2715 int d = data->m_comments.GetCount();
2716 wxLogTrace( traceMask, _T("(%s) comment count=%d"), __PRETTY_FUNCTION__, d );
2717 return d;
2718 }
2719
2720 //! Return the comment position.
2721 int
GetCommentPos() const2722 wxJSONValue::GetCommentPos() const
2723 {
2724 wxJSONRefData* data = GetRefData();
2725 wxJSON_ASSERT( data );
2726 return data->m_commentPos;
2727 }
2728
2729 //! Get the comment string's array.
2730 const wxArrayString&
GetCommentArray() const2731 wxJSONValue::GetCommentArray() const
2732 {
2733 wxJSONRefData* data = GetRefData();
2734 wxJSON_ASSERT( data );
2735
2736 return data->m_comments;
2737 }
2738
2739 //! Clear all comment strings
2740 void
ClearComments()2741 wxJSONValue::ClearComments()
2742 {
2743 wxJSONRefData* data = COW();
2744 wxJSON_ASSERT( data );
2745
2746 data->m_comments.clear();
2747 }
2748
2749
2750 //! Set the type of the stored value.
2751 /*!
2752 The function sets the type of the stored value as specified in
2753 the provided argument.
2754 If the actual type is equal to \c type, nothing happens and this
2755 JSON value object retains the original type and value.
2756 If the type differs, however, the original type and value are
2757 lost.
2758
2759 The function just sets the type of the object and not the
2760 value itself.
2761 If the object does not have a data structure it is allocated
2762 using the CreateRefData() function unless the type to be set
2763 is wxJSONTYPE_INVALID. In this case and if a data structure is
2764 not yet allocated, it is not allocated.
2765
2766 If the object already contains a data structure it is not deleted
2767 but the type is changed in the original data structure.
2768 Complex values in the old structure are cleared.
2769 The \c type argument can be one of the following:
2770
2771 \li wxJSONTYPE_INVALID: an empty (not initialized) JSON value
2772 \li wxJSONTYPE_NULL: a NULL value
2773 \li wxJSONTYPE_INT: an integer value
2774 \li wxJSONTYPE_UINT: an unsigned integer
2775 \li wxJSONTYPE_DOUBLE: a double precision number
2776 \li wxJSONTYPE_BOOL: a boolean
2777 \li wxJSONTYPE_CSTRING: a C string
2778 \li wxJSONTYPE_STRING: a wxString object
2779 \li wxJSONTYPE_ARRAY: an array of wxJSONValue objects
2780 \li wxJSONTYPE_OBJECT: a hashmap of key/value pairs where \e value is a wxJSONValue object
2781 \li wxJSONTYPE_LONG: a 32-bits integer value
2782 \li wxJSONTYPE_ULONG: an unsigned 32-bits integer
2783 \li wxJSONTYPE_INT64: a 64-bits integer value
2784 \li wxJSONTYPE_UINT64: an unsigned 64-bits integer
2785 \li wxJSONTYPE_SHORT: a signed short integer
2786 \li wxJSONTYPE_USHORT: an unsigned short integer
2787 \li wxJSONTYPE_MEMORYBUFF: a binary memory buffer
2788
2789 The integer storage depends on the platform: for platforms that support 64-bits
2790 integers, integers are always stored as 64-bits integers.
2791 On platforms that do not support 64-bits integers, ints are stored as \b long \b int.
2792 To know more about the internal representation of integers, read
2793 \ref json_internals_integer.
2794
2795 Note that there is no need to set a type for the object in order to assign
2796 a value to it.
2797 In other words, if you want to construct a JSON value which holds an integer
2798 value of 10, just use the specific constructor:
2799 \code
2800 wxJSONValue value( 10 );
2801 \endcode
2802 which sets the integer type and also the numeric value.
2803 Moreover, there is no need to set the type for none of the handled types,
2804 not only for primitive types but for complex types, too.
2805 For example, if you want to construct an array of JSON values, just use
2806 the default ctor and call the Append() member function which will append the
2807 first element to the array and will set the array type:
2808 \code
2809 wxJSONValue value;
2810 value.Append( "a string" );
2811 \endcode
2812 \sa GetType
2813 */
2814 wxJSONRefData*
SetType(wxJSONType type)2815 wxJSONValue::SetType( wxJSONType type )
2816 {
2817 wxJSONRefData* data = GetRefData();
2818 wxJSONType oldType = GetType();
2819
2820 // check that type is within the allowed range
2821 wxJSON_ASSERT((type >= wxJSONTYPE_INVALID) && (type <= wxJSONTYPE_MEMORYBUFF));
2822 if ( (type < wxJSONTYPE_INVALID) || (type > wxJSONTYPE_MEMORYBUFF) ) {
2823 type = wxJSONTYPE_INVALID;
2824 }
2825
2826 // the function unshares the referenced data but does not delete the
2827 // structure. This is because the wxJSON reader stores comments
2828 // that apear before the value in a temporary value of type wxJSONTYPE_INVALID
2829 // which is invalid and, next, it stores the JSON value in the same
2830 // wxJSONValue object.
2831 // If we would delete the structure using 'Unref()' we loose the
2832 // comments
2833 data = COW();
2834
2835 // do nothing if the actual type is the same as 'type'
2836 if ( type == oldType ) {
2837 return data;
2838 }
2839
2840 // change the type of the referened structure
2841 // NOTE: integer types are always stored as the generic integer types
2842 if ( type == wxJSONTYPE_LONG || type == wxJSONTYPE_INT64 || type == wxJSONTYPE_SHORT ) {
2843 type = wxJSONTYPE_INT;
2844 }
2845 if ( type == wxJSONTYPE_ULONG || type == wxJSONTYPE_UINT64 || type == wxJSONTYPE_USHORT ) {
2846 type = wxJSONTYPE_UINT;
2847 }
2848
2849 wxJSON_ASSERT( data );
2850 data->m_type = type;
2851
2852 // clears complex objects of the old type
2853 switch ( oldType ) {
2854 case wxJSONTYPE_STRING:
2855 data->m_valString.clear();
2856 break;
2857 case wxJSONTYPE_ARRAY:
2858 data->m_valArray.Clear();
2859 break;
2860 case wxJSONTYPE_OBJECT:
2861 data->m_valMap.clear();
2862 break;
2863 case wxJSONTYPE_MEMORYBUFF:
2864 // we first have to delete the actual memory buffer, if any
2865 if ( data->m_memBuff ) {
2866 delete data->m_memBuff;
2867 data->m_memBuff = 0;
2868 }
2869 break;
2870 default :
2871 // there is not need to clear primitive types
2872 break;
2873 }
2874
2875 // if the WXJSON_USE_CSTRING macro is not defined, the class forces
2876 // C-string to be stored as wxString objects
2877 #if !defined( WXJSON_USE_CSTRING )
2878 if ( data->m_type == wxJSONTYPE_CSTRING ) {
2879 data->m_type = wxJSONTYPE_STRING;
2880 }
2881 #endif
2882 return data;
2883 }
2884
2885 //! Return the line number of this JSON value object
2886 /*!
2887 The line number of a JSON value object is set to -1 when the
2888 object is constructed.
2889 The line number is set by the parser class, wxJSONReader, when
2890 a JSON text is read from a stream or a string.
2891 it is used when reading a comment line: comment lines that apear
2892 on the same line as a value are considered \b inline comments of
2893 the value.
2894 */
2895 int
GetLineNo() const2896 wxJSONValue::GetLineNo() const
2897 {
2898 // return ZERO if there is not a referenced data structure
2899 int n = 0;
2900 wxJSONRefData* data = GetRefData();
2901 if ( data != 0 ) {
2902 n = data->m_lineNo;
2903 }
2904 return n;
2905 }
2906
2907 //! Set the line number of this JSON value object.
2908 void
SetLineNo(int num)2909 wxJSONValue::SetLineNo( int num )
2910 {
2911 wxJSONRefData* data = COW();
2912 wxJSON_ASSERT( data );
2913 data->m_lineNo = num;
2914 }
2915
2916 //! Set the pointer to the referenced data.
2917 void
SetRefData(wxJSONRefData * data)2918 wxJSONValue::SetRefData(wxJSONRefData* data)
2919 {
2920 m_refData = data;
2921 }
2922
2923 //! Increments the referenced data counter.
2924 void
Ref(const wxJSONValue & clone)2925 wxJSONValue::Ref(const wxJSONValue& clone)
2926 {
2927 // nothing to be done
2928 if (m_refData == clone.m_refData)
2929 return;
2930
2931 // delete reference to old data
2932 UnRef();
2933
2934 // reference new data
2935 if ( clone.m_refData ) {
2936 m_refData = clone.m_refData;
2937 ++(m_refData->m_refCount);
2938 }
2939 }
2940
2941 //! Unreferences the shared data
2942 /*!
2943 The function decrements the number of shares in wxJSONRefData::m_refCount
2944 and if it is ZERO, deletes the referenced data.
2945 It is called by the destructor and by the copy-on-write functions.
2946 */
2947 void
UnRef()2948 wxJSONValue::UnRef()
2949 {
2950 if ( m_refData ) {
2951 wxASSERT_MSG( m_refData->m_refCount > 0, _T("invalid ref data count") );
2952
2953 if ( --m_refData->m_refCount == 0 ) {
2954 delete m_refData;
2955 m_refData = NULL;
2956 }
2957 }
2958 }
2959
2960 //! Makes an exclusive copy of shared data
2961 void
UnShare()2962 wxJSONValue::UnShare()
2963 {
2964 AllocExclusive();
2965 }
2966
2967
2968 //! Do a deep copy of the other object.
2969 /*!
2970 This function allocates a new ref-data structure and copies it
2971 from the object \c other.
2972 */
2973 void
DeepCopy(const wxJSONValue & other)2974 wxJSONValue::DeepCopy( const wxJSONValue& other )
2975 {
2976 UnRef();
2977 wxJSONRefData* data = CloneRefData( other.m_refData );
2978 SetRefData( data );
2979 }
2980
2981 //! Return the pointer to the referenced data structure.
2982 wxJSONRefData*
GetRefData() const2983 wxJSONValue::GetRefData() const
2984 {
2985 wxJSONRefData* data = m_refData;
2986 return data;
2987 }
2988
2989
2990 //! Make a copy of the referenced data.
2991 /*!
2992 The function allocates a new instance of the wxJSONRefData
2993 structure, copies the content of \c other and returns the pointer
2994 to the newly created structure.
2995 This function is called by the wxObject::UnRef() function
2996 when a non-const member function is called on multiple
2997 referenced data.
2998 */
2999 wxJSONRefData*
CloneRefData(const wxJSONRefData * otherData) const3000 wxJSONValue::CloneRefData( const wxJSONRefData* otherData ) const
3001 {
3002 wxJSON_ASSERT( otherData );
3003
3004 // make a static cast to pointer-to-wxJSONRefData
3005 const wxJSONRefData* other = otherData;
3006
3007 // allocate a new instance of wxJSONRefData using the default
3008 // ctor; we cannot use the copy ctor of a wxJSONRefData
3009 wxJSONRefData* data = new wxJSONRefData();
3010
3011 // copy the referenced data structure's data members
3012 data->m_type = other->m_type;
3013 data->m_value = other->m_value;
3014 data->m_commentPos = other->m_commentPos;
3015 data->m_comments = other->m_comments;
3016 data->m_lineNo = other->m_lineNo;
3017 data->m_valString = other->m_valString;
3018 data->m_valArray = other->m_valArray;
3019 data->m_valMap = other->m_valMap;
3020
3021 // if the data contains a wxMemoryBuffer object, then we have
3022 // to make a deep copy of the buffer by allocating a new one because
3023 // wxMemoryBuffer is not a copy-on-write structure
3024 if ( other->m_memBuff ) {
3025 data->m_memBuff = new wxMemoryBuffer();
3026 const void* ptr = data->m_memBuff->GetData();
3027 size_t len = data->m_memBuff->GetDataLen();
3028 if ( data->m_memBuff && len ) {
3029 data->m_memBuff->AppendData( ptr, len );
3030 }
3031 }
3032
3033 wxLogTrace( cowTraceMask, _T("(%s) CloneRefData() PROGR: other=%d data=%d"),
3034 __PRETTY_FUNCTION__, other->GetRefCount(), data->GetRefCount() );
3035
3036 return data;
3037 }
3038
3039 //! Create a new data structure
3040 /*!
3041 The function allocates a new instance of the wxJSONRefData
3042 structure and returns its pointer.
3043 The type of the JSON value is set to wxJSONTYPE_INVALID (=
3044 a not initialized value).
3045 */
3046 wxJSONRefData*
CreateRefData() const3047 wxJSONValue::CreateRefData() const
3048 {
3049 wxJSONRefData* data = new wxJSONRefData();
3050 data->m_type = wxJSONTYPE_INVALID;
3051 return data;
3052 }
3053
3054
3055
3056 //! Make sure the referenced data is unique
3057 /*!
3058 This function is called by all non-const member functions and makes
3059 sure that the referenced data is unique by calling \b UnShare()
3060 If the referenced data is shared acrosss other wxJSONValue instances,
3061 the \c UnShare() function makes a private copy of the shared data.
3062 */
3063 wxJSONRefData*
COW()3064 wxJSONValue::COW()
3065 {
3066 wxJSONRefData* data = GetRefData();
3067 wxLogTrace( cowTraceMask, _T("(%s) COW() START data=%p data->m_count=%d"),
3068 __PRETTY_FUNCTION__, data, data->GetRefCount());
3069 UnShare();
3070 data = GetRefData();
3071 wxLogTrace( cowTraceMask, _T("(%s) COW() END data=%p data->m_count=%d"),
3072 __PRETTY_FUNCTION__, data, data->GetRefCount());
3073 return GetRefData();
3074 }
3075
3076 //! Makes a private copy of the referenced data
3077 void
AllocExclusive()3078 wxJSONValue::AllocExclusive()
3079 {
3080 if ( !m_refData ) {
3081 m_refData = CreateRefData();
3082 }
3083 else if ( m_refData->GetRefCount() > 1 ) {
3084 // note that ref is not going to be destroyed in this case
3085 const wxJSONRefData* ref = m_refData;
3086 UnRef();
3087
3088 // ... so we can still access it
3089 m_refData = CloneRefData(ref);
3090 }
3091 //else: ref count is 1, we are exclusive owners of m_refData anyhow
3092
3093 wxASSERT_MSG( m_refData && m_refData->GetRefCount() == 1,
3094 _T("wxObject::AllocExclusive() failed.") );
3095 }
3096
3097 //! Convert memory buffer object to a string representation.
3098 /*/
3099 The fucntion returns a string representation of the data contained in the
3100 memory buffer object \c buff.
3101 The string is conposed of two hexadecimal digits for every byte contained
3102 in the memory buffer; bytes are separated by a space character.
3103 The string starts with the actual lenght of the data enclosed in parenthesis.
3104 The string will contain \c len bytes if \c len is less than the length
3105 of the actual data in \c buff.
3106 Note that the (len) printed in the output referes to the length of the buffer
3107 which may be greater than the length that has to be printed.
3108
3109 \b Example:
3110 This is an example of printing a memory buffer object that contains 10 bytes:
3111 \code
3112 0x80974653 (10) 00 01 02 03 04 05 06 07 08 09
3113 \endcode
3114 */
3115 wxString
MemoryBuffToString(const wxMemoryBuffer & buff,size_t len)3116 wxJSONValue::MemoryBuffToString( const wxMemoryBuffer& buff, size_t len )
3117 {
3118 size_t buffLen = buff.GetDataLen();
3119 void* ptr = buff.GetData();
3120 wxString s = MemoryBuffToString( ptr, MIN( buffLen, len ), buffLen );
3121 return s;
3122 }
3123
3124
3125 //! Convert a binary memory buffer to a string representation.
3126 /*/
3127 The function returns a string representation of the data contained in the
3128 binary memory buffer pointed to by \c buff for \c len bytes.
3129 The string is composed of two hexadecimal digits for every byte contained
3130 in the memory buffer; bytes are separated by a space character.
3131 The string starts with pointer to binary data followed by the lenght of the
3132 data enclosed in parenthesis.
3133
3134 \b Example:
3135 This is an example of printing ten bytes from a memory buffer:
3136 \code
3137 0x80974653 (10) 00 01 02 03 04 05 06 07 08 09
3138 \endcode
3139
3140 @param buff the pointer to the memory buffer data
3141 @len the length of the data that has to be printed
3142 @actualLen the real lenght of the memory buffer that has to be printed
3143 just afetr the pointer; may be greater than \c len. If this parameter
3144 is -1 then it is equal to \c len
3145 */
3146 wxString
MemoryBuffToString(const void * buff,size_t len,size_t actualLen)3147 wxJSONValue::MemoryBuffToString( const void* buff, size_t len, size_t actualLen )
3148 {
3149 wxString s;
3150 size_t buffLen = actualLen;
3151 if (buffLen == (size_t) -1 ) {
3152 buffLen = len;
3153 }
3154 s.Printf( _T("%p (%u) "), buff, buffLen );
3155 unsigned char* ptr = (unsigned char*) buff;
3156 for ( unsigned int i = 0; i < len; i++ ) {
3157 unsigned char c = *ptr;
3158 ++ptr;
3159 // now convert the character
3160 char c1 = c / 16;
3161 char c2 = c % 16;
3162 c1 += '0';
3163 c2 += '0';
3164 if ( c1 > '9' ) {
3165 c1 += 7;
3166 }
3167 if ( c2 > '9' ) {
3168 c2 += 7;
3169 }
3170 s.Append( c1, 1 );
3171 s.Append( c2, 1 );
3172 s.Append( ' ', 1 ); // a space separates the bytes
3173 }
3174 return s;
3175 }
3176
3177 //! Compares two memory buffer objects
3178 /*!
3179 The function is the counterpart of the comparison operator == for two wxMemoryBuffer
3180 objects.
3181 You may noticed that the wxMemoryBuffer class does not define comparison operators so
3182 if you write a code snippset like the following:
3183 \code
3184 wxMemoryBuffer b1;
3185 wxMemoryBuffer b2;
3186 b1.AppendData( "1234567890", 10 );
3187 b2.AppendData( "1234567890", 10 );
3188 bool r = b1 == b2;
3189 \endcode
3190
3191 you may expect that \b r is TRUE, because both objects contain the same data.
3192 This is not true. The result you get is FALSE because the default comparison operator
3193 is used, which just compares the data members of the class.
3194 The data member is the pointer to the allocated memory that contains the data and
3195 they are not equal.
3196 This function uses the (fast) \b memcmp function to compare the actual data
3197 contained in the nenory buffer objects thus doing a deep comparison.
3198 The function returns the return value of \b memcmp:
3199
3200 the memcmp() function returns an integer less than, equal to, or
3201 greater than zero if the first n bytes of \c buff1 is found, respectively, to
3202 be less than, to match, or be greater than the first n bytes of \c buff2.
3203 */
3204 int
CompareMemoryBuff(const wxMemoryBuffer & buff1,const wxMemoryBuffer & buff2)3205 wxJSONValue::CompareMemoryBuff( const wxMemoryBuffer& buff1, const wxMemoryBuffer& buff2 )
3206 {
3207 int r;
3208 size_t buff1Len = buff1.GetDataLen();
3209 size_t buff2Len = buff2.GetDataLen();
3210 if ( buff1Len > buff2Len ) {
3211 r = 1;
3212 }
3213 else if ( buff1Len < buff2Len ) {
3214 r = -1;
3215 }
3216 else {
3217 r = memcmp( buff1.GetData(), buff2.GetData(), buff1Len );
3218 }
3219 return r;
3220 }
3221
3222 //! Compares a memory buffer object and a memory buffer
3223 /*!
3224 The function compares the data contained in a memory buffer object with a
3225 memory buffer.
3226 This function uses the (fast) \b memcmp function to compare the actual data
3227 contained in the nenory buffer object thus doing a deep comparison.
3228 The function returns the return value of \b memcmp:
3229
3230 The memcmp() function returns an integer less than, equal to, or
3231 greater than zero if the first n bytes of \c buff1 is found, respectively, to
3232 be less than, to match, or be greater than the first n bytes of \c buff2.
3233 */
3234 int
CompareMemoryBuff(const wxMemoryBuffer & buff1,const void * buff2)3235 wxJSONValue::CompareMemoryBuff( const wxMemoryBuffer& buff1, const void* buff2 )
3236 {
3237 int r;
3238 size_t buff1Len = buff1.GetDataLen();
3239 r = memcmp( buff1.GetData(), buff2, buff1Len );
3240 return r;
3241 }
3242
3243
3244 //! Converts an array of INTs to a memory buffer
3245 /*!
3246 This static function converts an array of INTs stored in a wxJSONvalue object
3247 into a memory buffer object.
3248 The wxJSONvalue object passed as parameter must be of type ARRAY and must contain
3249 INT types whose values are between 0 and 255.
3250
3251 Every element of the array si converted to a BYTE value and appended to the returned
3252 wxMemoryBuffer object. The following rules apply in the conversion:
3253 \li if \c value is not an ARRAY type, an empty memory buffer is returned
3254 \li if the \c value array contains elements of type other than INT, those
3255 elements are ignored
3256 \li if the \c value array contains elements of type INT which value is outside the
3257 range 0..255, those elements are ignored
3258 \li if the \c value array contains only ignored elements an empty wxMemoryBuffer
3259 object is returned.
3260
3261 This function can be used to get a memory buffer object from valid JSON text.
3262 Please note that the wxJSONReader cannot know which array of INTs represent a binary
3263 memory buffer unless you use the \b wxJSON \e memory \e buffer extension in the writer and
3264 in the reader.
3265 */
3266 wxMemoryBuffer
ArrayToMemoryBuff(const wxJSONValue & value)3267 wxJSONValue::ArrayToMemoryBuff( const wxJSONValue& value )
3268 {
3269 wxMemoryBuffer buff;
3270 if ( value.IsArray() ) {
3271 int len = value.Size();
3272 for ( int i = 0; i < len; i++ ) {
3273 short int byte; unsigned char c;
3274 // we do not use opertaor [] because it is not const
3275 // bool r = value[i].AsShort( byte );
3276 bool r = value.ItemAt(i).AsShort( byte );
3277 if ( r && ( byte >= 0 && byte <= 255 ) ) {
3278 c = (unsigned char) byte;
3279 buff.AppendByte( c );
3280 }
3281 }
3282 }
3283 return buff;
3284 }
3285
3286
3287 /*************************************************************************
3288
3289 64-bits integer support
3290
3291 *************************************************************************/
3292
3293 #if defined( wxJSON_64BIT_INT)
3294
3295
3296 //! \overload wxJSONValue()
wxJSONValue(wxInt64 i)3297 wxJSONValue::wxJSONValue( wxInt64 i )
3298 {
3299 m_refData = 0;
3300 wxJSONRefData* data = Init( wxJSONTYPE_INT );
3301 wxJSON_ASSERT( data );
3302 if ( data != 0 ) {
3303 data->m_value.VAL_INT = i;
3304 }
3305 }
3306
3307 //! \overload wxJSONValue()
wxJSONValue(wxUint64 ui)3308 wxJSONValue::wxJSONValue( wxUint64 ui )
3309 {
3310 m_refData = 0;
3311 wxJSONRefData* data = Init( wxJSONTYPE_UINT );
3312 wxJSON_ASSERT( data );
3313 if ( data != 0 ) {
3314 data->m_value.VAL_UINT = ui;
3315 }
3316 }
3317
3318 //! Return TRUE if the stored value is a 32-bits integer
3319 /*!
3320 This function is only available on 64-bits platforms and returns
3321 TRUE if, and only if, the stored value is of type \b wxJSONTYPE_INT
3322 and the numeric value fits in a 32-bits signed integer.
3323 The function just calls IsLong() and returns the value returned by
3324 that function.
3325 The use of this function is deprecated: use \c IsLong() instead
3326 */
3327 bool
IsInt32() const3328 wxJSONValue::IsInt32() const
3329 {
3330 bool r = IsLong();
3331 return r;
3332 }
3333
3334 //! Return TRUE if the stored value is a unsigned 32-bits integer
3335 /*!
3336 This function is only available on 64-bits platforms and returns
3337 TRUE if, and only if, the stored value is of type \b wxJSONTYPE_UINT
3338 and the numeric value fits in a 32-bits unsigned integer.
3339 The function just calls IsULong() and returns the value returned by
3340 that function.
3341 The use of this function is deprecated: use \c IsULong() instead
3342 */
3343 bool
IsUInt32() const3344 wxJSONValue::IsUInt32() const
3345 {
3346 bool r = IsULong();
3347 return r;
3348 }
3349
3350
3351 //! Return TRUE if the stored value is integer.
3352 /*!
3353 This function returns TRUE if the stored value is of
3354 type signed integer.
3355 In other words, the function returns TRUE if the \c wxJSONRefData::m_type
3356 data member is of type \c wxJSONTYPE_INT
3357 The function is only available if 64-bits integer support is enabled.
3358
3359 \sa \ref json_internals_integer
3360 */
3361 bool
IsInt64() const3362 wxJSONValue::IsInt64() const
3363 {
3364 wxJSONRefData* data = GetRefData();
3365 wxJSON_ASSERT( data );
3366 bool r = false;
3367 if ( data->m_type == wxJSONTYPE_INT ) {
3368 r = true;
3369 }
3370 return r;
3371 }
3372
3373
3374 //! Return TRUE if the stored value is a unsigned integer
3375 /*!
3376 This function returns TRUE if the stored value is of
3377 type unsigned integer.
3378 In other words, the function returns TRUE if the \c wxJSONRefData::m_type
3379 data member is of type \c wxJSONTYPE_UINT.
3380 The function is only available if 64-bits integer support is enabled.
3381
3382 \sa \ref json_internals_integer
3383 */
3384 bool
IsUInt64() const3385 wxJSONValue::IsUInt64() const
3386 {
3387 wxJSONRefData* data = GetRefData();
3388 wxJSON_ASSERT( data );
3389 bool r = false;
3390 if ( data->m_type == wxJSONTYPE_UINT ) {
3391 r = true;
3392 }
3393 return r;
3394 }
3395
3396 //! Returns the low-order 32 bits of the value as an integer
3397 /*!
3398 This function is only available on 64-bits platforms and returns
3399 the low-order 32-bits of the integer stored in the JSON value.
3400 Note that all integer types are stored as \b wx(U)Int64 data types by
3401 the JSON value class and that the function does not check that the
3402 numeric value fits in a 32-bit integer.
3403 The function just calls AsLong() and casts the value in a wxInt32 data
3404 type
3405
3406 \sa \ref wxjson_tutorial_get
3407 */
3408 wxInt32
AsInt32() const3409 wxJSONValue::AsInt32() const
3410 {
3411 wxInt32 i;
3412 i = (wxInt32) AsLong();
3413 return i;
3414 }
3415
3416 //! Returns the low-order 32 bits of the value as an unsigned integer
3417 /*!
3418 This function is only available on 64-bits platforms and returns
3419 the low-order 32-bits of the integer stored in the JSON value.
3420 Note that all integer types are stored as \b wx(U)Int64 data types by
3421 the JSON value class and that the function does not check that the
3422 numeric value fits in a 32-bit integer.
3423 The function just calls AsULong() and casts the value in a wxUInt32 data
3424 type
3425
3426 \sa \ref wxjson_tutorial_get
3427 */
3428 wxUint32
AsUInt32() const3429 wxJSONValue::AsUInt32() const
3430 {
3431 wxUint32 ui;
3432 ui = (wxUint32) AsULong();
3433 return ui;
3434 }
3435
3436
3437 //! Return the numeric value as a 64-bit integer.
3438 /*!
3439 This function is only available on 64-bits platforms and returns
3440 the numeric value as a 64-bit integer.
3441
3442 Note that the function does not check that the type of the
3443 value is actually an integer and it just returns the content
3444 of the wxJSONValueHolder union.
3445 However, in debug builds, the function ASSERTs that the
3446 type of the stored value is wxJSONTYPE_INT.
3447
3448 \sa \ref json_internals_integer
3449 \sa \ref wxjson_tutorial_get
3450 */
3451 wxInt64
AsInt64() const3452 wxJSONValue::AsInt64() const
3453 {
3454 wxJSONRefData* data = GetRefData();
3455 wxJSON_ASSERT( data );
3456 wxInt64 i64 = data->m_value.m_valInt64;
3457
3458 wxJSON_ASSERT( IsInt64()); // exapnds only in debug builds
3459 return i64;
3460 }
3461
3462 //! Return the numeric value as a 64-bit unsigned integer.
3463 /*!
3464 This function is only available on 64-bits platforms and returns
3465 the numeric value as a 64-bit unsigned integer.
3466
3467 Note that the function does not check that the type of the
3468 value is actually an integer and it just returns the content
3469 of the wxJSONValueHolder union.
3470 However, in debug builds, the function wxJSON_ASSERTs that the
3471 type of the stored value is wxJSONTYPE_UINT.
3472
3473 \sa \ref json_internals_integer
3474 \sa \ref wxjson_tutorial_get
3475 */
3476 wxUint64
AsUInt64() const3477 wxJSONValue::AsUInt64() const
3478 {
3479 wxJSONRefData* data = GetRefData();
3480 wxJSON_ASSERT( data );
3481 wxUint64 ui64 = data->m_value.m_valUInt64;
3482
3483 wxJSON_ASSERT( IsUInt64()); // exapnds only in debug builds
3484 return ui64;
3485 }
3486
3487 bool
AsInt32(wxInt32 & i32) const3488 wxJSONValue::AsInt32( wxInt32& i32 ) const
3489 {
3490 bool r = IsInt32();
3491 if ( r ) {
3492 i32 = AsInt32();
3493 }
3494 return r;
3495 }
3496
3497 bool
AsUInt32(wxUint32 & ui32) const3498 wxJSONValue::AsUInt32( wxUint32& ui32 ) const
3499 {
3500 bool r = IsUInt32();
3501 if ( r ) {
3502 ui32 = AsUInt32();
3503 }
3504 return r;
3505 }
3506
3507 bool
AsInt64(wxInt64 & i64) const3508 wxJSONValue::AsInt64( wxInt64& i64 ) const
3509 {
3510 bool r = IsInt64();
3511 if ( r ) {
3512 i64 = AsInt64();
3513 }
3514 return r;
3515 }
3516
3517 bool
AsUInt64(wxUint64 & ui64) const3518 wxJSONValue::AsUInt64( wxUint64& ui64 ) const
3519 {
3520 bool r = IsUInt64();
3521 if ( r ) {
3522 ui64 = AsUInt64();
3523 }
3524 return r;
3525 }
3526
3527 //! \overload Append( const wxJSONValue& )
3528 wxJSONValue&
Append(wxInt64 i)3529 wxJSONValue::Append( wxInt64 i )
3530 {
3531 wxJSONValue v( i );
3532 wxJSONValue& r = Append( v );
3533 return r;
3534 }
3535
3536 //! \overload Append( const wxJSONValue& )
3537 wxJSONValue&
Append(wxUint64 ui)3538 wxJSONValue::Append( wxUint64 ui )
3539 {
3540 wxJSONValue v( ui );
3541 wxJSONValue& r = Append( v );
3542 return r;
3543 }
3544
3545
3546 //! \overload operator = (int)
3547 wxJSONValue&
operator =(wxInt64 i)3548 wxJSONValue::operator = ( wxInt64 i )
3549 {
3550 wxJSONRefData* data = SetType( wxJSONTYPE_INT );
3551 data->m_value.VAL_INT = i;
3552 return *this;
3553 }
3554
3555 //! \overload operator = (int)
3556 wxJSONValue&
operator =(wxUint64 ui)3557 wxJSONValue::operator = ( wxUint64 ui )
3558 {
3559 wxJSONRefData* data = SetType( wxJSONTYPE_UINT );
3560 data->m_value.VAL_UINT = ui;
3561 return *this;
3562 }
3563
3564
3565 #endif // defined( wxJSON_64BIT_INT )
3566
3567
3568
3569
3570 /*
3571 {
3572 }
3573 */
3574
3575