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 &lt;invalid&gt;
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