1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        jsonval.h
3 // Purpose:     the wxJSONValue class: it holds a JSON value
4 // Author:      Luciano Cattani
5 // Created:     2007/09/15
6 // RCS-ID:      $Id: jsonval.h,v 1.4 2008/01/10 21:27:15 luccat Exp $
7 // Copyright:   (c) 2007 Luciano Cattani
8 // Licence:     wxWidgets licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 #if !defined(_WX_JSONVAL_H)
12 #define _WX_JSONVAL_H
13 
14 #ifdef __GNUG__
15     #pragma interface "jsonval.h"
16 #endif
17 
18 // For compilers that support precompilation, includes "wx/wx.h".
19 #include "wx/wxprec.h"
20 
21 #ifdef __BORLANDC__
22     #pragma hdrstop
23 #endif
24 
25 // for all others, include the necessary headers (this file is usually all you
26 // need because it includes almost all "standard" wxWidgets headers)
27 #ifndef WX_PRECOMP
28     #include <wx/object.h>
29     #include <wx/hashmap.h>
30     #include <wx/dynarray.h>
31     #include <wx/arrstr.h>
32 #endif
33 
34 
35 #include "json_defs.h"
36 
37 // forward declarations
38 class WXDLLIMPEXP_JSON wxJSONReader;
39 class WXDLLIMPEXP_JSON wxJSONRefData;
40 
41 #if defined(wxJSON_USE_STL)
42     // if compiling on MinGW we use the STL-style declaration of wxWidget's
43     // container classes
44     class WXDLLIMPEXP_JSON wxJSONValue;
45     WX_DECLARE_OBJARRAY(wxJSONValue, wxJSONInternalArray);
46     WX_DECLARE_STRING_HASH_MAP(wxJSONValue, wxJSONInternalMap);
47 #else
48     class WXDLLIMPEXP_JSON wxJSONInternalMap;
49     class WXDLLIMPEXP_JSON wxJSONInternalArray;
50 #endif
51 
52 
53 //! The type of the value held by the wxJSONRefData class
54 enum wxJSONType {
55     wxJSONTYPE_INVALID = 0,  /*!< the object is not uninitialized        */
56     wxJSONTYPE_NULL,       /*!< the object contains a NULL value         */
57     wxJSONTYPE_INT,        /*!< the object contains an integer           */
58     wxJSONTYPE_UINT,       /*!< the object contains an unsigned integer  */
59     wxJSONTYPE_DOUBLE,     /*!< the object contains a double             */
60     wxJSONTYPE_STRING,     /*!< the object contains a wxString object    */
61     wxJSONTYPE_CSTRING,    /*!< the object contains a static C-string    */
62     wxJSONTYPE_BOOL,       /*!< the object contains a boolean            */
63     wxJSONTYPE_ARRAY,      /*!< the object contains an array of values   */
64     wxJSONTYPE_OBJECT,     /*!< the object contains a map of keys/values */
65     wxJSONTYPE_LONG,       /*!< the object contains a 32-bit integer     */
66     wxJSONTYPE_INT64,      /*!< the object contains a 64-bit integer     */
67     wxJSONTYPE_ULONG,      /*!< the object contains an unsigned 32-bit integer  */
68     wxJSONTYPE_UINT64,     /*!< the object contains an unsigned 64-bit integer  */
69     wxJSONTYPE_SHORT,      /*!< the object contains a 16-bit integer            */
70     wxJSONTYPE_USHORT,     /*!< the object contains a 16-bit unsigned integer   */
71     wxJSONTYPE_MEMORYBUFF  /*!< the object contains a binary memory buffer   */
72 };
73 
74 // the comment position: every value only has one comment position
75 // althrough comments may be splitted into several lines
76 enum {
77   wxJSONVALUE_COMMENT_DEFAULT = 0,
78   wxJSONVALUE_COMMENT_BEFORE,
79   wxJSONVALUE_COMMENT_AFTER,
80   wxJSONVALUE_COMMENT_INLINE,
81 };
82 
83 /***********************************************************************
84 
85             class wxJSONValue
86 
87 ***********************************************************************/
88 
89 
90 // class WXDLLIMPEXP_JSON wxJSONValue : public wxObject
91 class WXDLLIMPEXP_JSON wxJSONValue {
92     friend class wxJSONReader;
93 
94  public:
95     // ctors and dtor
96     wxJSONValue();
97     explicit wxJSONValue(wxJSONType type);
98     explicit wxJSONValue(int i);
99     explicit wxJSONValue(unsigned int i);
100     explicit wxJSONValue(short i);
101     explicit wxJSONValue(unsigned short i);
102     explicit wxJSONValue(long int i);
103     explicit wxJSONValue(unsigned long int i);
104 #if defined(wxJSON_64BIT_INT)
105     explicit wxJSONValue(wxInt64 i);
106     explicit wxJSONValue(wxUint64 ui);
107 #endif
108     explicit wxJSONValue(bool b);
109     explicit wxJSONValue(double d);
110     explicit wxJSONValue(const wxChar* str);     // assume static ASCIIZ strings
111     explicit wxJSONValue(const wxString& str);
112     explicit wxJSONValue(const wxMemoryBuffer& buff);
113     wxJSONValue(const void* buff, size_t len);
114     wxJSONValue(const wxJSONValue& other);
115     virtual ~wxJSONValue();
116 
117     // functions for retrieving the value type
118     wxJSONType  GetType() const;
119     bool IsValid() const;
120     bool IsNull() const;
121     bool IsInt() const;
122     bool IsUInt() const;
123     bool IsShort() const;
124     bool IsUShort() const;
125     bool IsLong() const;
126     bool IsULong() const;
127 #if defined(wxJSON_64BIT_INT)
128     bool IsInt32() const;
129     bool IsInt64() const;
130     bool IsUInt32() const;
131     bool IsUInt64() const;
132 #endif
133     bool IsBool() const;
134     bool IsDouble() const;
135     bool IsString() const;
136     bool IsCString() const;
137     bool IsArray() const;
138     bool IsObject() const;
139     bool IsMemoryBuff() const;
140 
141     // function for retireving the value as ...
142     int            AsInt() const;
143     unsigned int   AsUInt() const;
144     short          AsShort() const;
145     unsigned short AsUShort() const;
146     long int       AsLong() const;
147     unsigned long  AsULong() const;
148     bool        AsInt(int& i) const;
149     bool        AsUInt(unsigned int& ui) const;
150     bool        AsShort(short int& s) const;
151     bool        AsUShort(unsigned short& us) const;
152     bool        AsLong(long int& l) const;
153     bool        AsULong(unsigned long& ul) const;
154 #if defined(wxJSON_64BIT_INT)
155     wxInt32        AsInt32() const;
156     wxUint32       AsUInt32() const;
157     wxInt64        AsInt64() const;
158     wxUint64       AsUInt64() const;
159     bool        AsInt32(wxInt32& i32) const;
160     bool        AsUInt32(wxUint32& ui32) const;
161     bool        AsInt64(wxInt64& i64) const;
162     bool        AsUInt64(wxUint64& ui64) const;
163 #endif
164     bool           AsBool() const;
165     double         AsDouble() const;
166     wxString       AsString() const;
167     const wxChar*  AsCString() const;
168     bool        AsBool(bool& b) const;
169     bool        AsDouble(double& d) const;
170     bool        AsString(wxString& str) const;
171     bool        AsCString(wxChar* ch) const;
172     wxMemoryBuffer AsMemoryBuff() const;
173     bool        AsMemoryBuff(wxMemoryBuffer& buff) const;
174 
175     const wxJSONInternalMap*   AsMap() const;
176     const wxJSONInternalArray* AsArray() const;
177 
178     // get members names, size and other info
179     bool      HasMember(unsigned index) const;
180     bool      HasMember(const wxString& key) const;
181     int       Size() const;
182     wxArrayString  GetMemberNames() const;
183 
184     // appending items, resizing and deleting items
185     wxJSONValue& Append(const wxJSONValue& value);
186     wxJSONValue& Append(bool b);
187     wxJSONValue& Append(int i);
188     wxJSONValue& Append(unsigned int ui);
189     wxJSONValue& Append(short int i);
190     wxJSONValue& Append(unsigned short int ui);
191     wxJSONValue& Append(long int l);
192     wxJSONValue& Append(unsigned long int ul);
193 #if defined(wxJSON_64BIT_INT)
194     wxJSONValue& Append(wxInt64 i);
195     wxJSONValue& Append(wxUint64 ui);
196 #endif
197     wxJSONValue& Append(double d);
198     wxJSONValue& Append(const wxChar* str);
199     wxJSONValue& Append(const wxString& str);
200     wxJSONValue& Append(const wxMemoryBuffer& buff);
201     wxJSONValue& Append(const void* buff, size_t len);
202     bool         Remove(int index);
203     bool         Remove(const wxString& key);
204     void         Clear();
205     bool         Cat(const wxChar* str);
206     bool         Cat(const wxString& str);
207     bool         Cat(const wxMemoryBuffer& buff);
208 
209     // retrieve an item
210     wxJSONValue& Item(unsigned index);
211     wxJSONValue& Item(const wxString& key);
212     wxJSONValue  ItemAt(unsigned index) const;
213     wxJSONValue  ItemAt(const wxString& key) const;
214 
215     wxJSONValue& operator[] (unsigned index);
216     wxJSONValue& operator[] (const wxString& key);
217 
218     wxJSONValue& operator = (int i);
219     wxJSONValue& operator = (unsigned int ui);
220     wxJSONValue& operator = (short int i);
221     wxJSONValue& operator = (unsigned short int ui);
222     wxJSONValue& operator = (long int l);
223     wxJSONValue& operator = (unsigned long int ul);
224 #if defined(wxJSON_64BIT_INT)
225     wxJSONValue& operator = (wxInt64 i);
226     wxJSONValue& operator = (wxUint64 ui);
227 #endif
228     wxJSONValue& operator = (bool b);
229     wxJSONValue& operator = (double d);
230     wxJSONValue& operator = (const wxChar* str);
231     wxJSONValue& operator = (const wxString& str);
232     wxJSONValue& operator = (const wxMemoryBuffer& buff);
233     // wxJSONValue& operator = (const void* buff, size_t len); cannot be declared
234     wxJSONValue& operator = (const wxJSONValue& value);
235 
236     // get the value or a default value
237     wxJSONValue  Get(const wxString& key, const wxJSONValue& defaultValue) const;
238 
239     // comparison function
240     bool         IsSameAs(const wxJSONValue& other) const;
241 
242     // comment-related functions
243     int      AddComment(const wxString& str, int position = wxJSONVALUE_COMMENT_DEFAULT);
244     int      AddComment(const wxArrayString& comments, int position = wxJSONVALUE_COMMENT_DEFAULT);
245     wxString GetComment(int idx = -1) const;
246     int      GetCommentPos() const;
247     int      GetCommentCount() const;
248     void     ClearComments();
249     const wxArrayString& GetCommentArray() const;
250 
251     // debugging functions
252     wxString         GetInfo() const;
253     wxString         Dump(bool deep = false, int mode = 0) const;
254 
255     //misc functions
256     wxJSONRefData*   GetRefData() const;
257     wxJSONRefData*   SetType(wxJSONType type);
258     int              GetLineNo() const;
259     void             SetLineNo(int num);
260 
261     // public static functions: mainly used for debugging
262     static  wxString TypeToString(wxJSONType type);
263     static  wxString MemoryBuffToString(const wxMemoryBuffer& buff, size_t len = -1);
264     static  wxString MemoryBuffToString(const void* buff, size_t len, size_t actualLen = -1);
265     static  int      CompareMemoryBuff(const wxMemoryBuffer& buff1, const wxMemoryBuffer& buff2);
266     static  int      CompareMemoryBuff(const wxMemoryBuffer& buff1, const void* buff2);
267     static wxMemoryBuffer ArrayToMemoryBuff(const wxJSONValue& value);
268 
269  protected:
270     wxJSONValue*  Find(unsigned index) const;
271     wxJSONValue*  Find(const wxString& key) const;
272     void          DeepCopy(const wxJSONValue& other);
273 
274     wxJSONRefData*  Init(wxJSONType type);
275     wxJSONRefData*  COW();
276 
277     // overidden from wxObject
278     virtual wxJSONRefData*  CloneRefData(const wxJSONRefData *data) const;
279     virtual wxJSONRefData*  CreateRefData() const;
280 
281     void            SetRefData(wxJSONRefData* data);
282     void            Ref(const wxJSONValue& clone);
283     void            UnRef();
284     void            UnShare();
285     void            AllocExclusive();
286 
287     //! the referenced data
288     wxJSONRefData*  m_refData;
289 
290 
291     // used for debugging purposes: only in debug builds.
292 #if defined(WXJSON_USE_VALUE_COUNTER)
293     int         m_progr;
294     static int  sm_progr;
295 #endif
296 };
297 
298 
299 #if !defined(wxJSON_USE_STL)
300     // if using wxWidget's implementation of container classes we declare
301     // the OBJARRAY are HASH_MAP _after_ the wxJSONValue is fully known
302     WX_DECLARE_OBJARRAY(wxJSONValue, wxJSONInternalArray);
303     WX_DECLARE_STRING_HASH_MAP(wxJSONValue, wxJSONInternalMap);
304 #endif
305 
306 
307 /***********************************************************************
308 
309             class wxJSONRefData
310 
311 ***********************************************************************/
312 
313 
314 
315 
316 //! The actual value held by the wxJSONValue class (internal use)
317 /*!
318  Note that this structure is a \b union as in versions prior to 0.4.x
319  The union just stores primitive types and not complex types which are
320  stored in separate data members of the wxJSONRefData structure.
321 
322  This organization give us more flexibility when retrieving compatible
323  types such as ints unsigned ints, long and so on.
324  To know more about the internal structure of the wxJSONValue class
325  see \ref pg_json_internals.
326 */
327 union wxJSONValueHolder  {
328     int             m_valInt;
329     unsigned int    m_valUInt;
330     short int       m_valShort;
331     unsigned short  m_valUShort;
332     long int        m_valLong;
333     unsigned long   m_valULong;
334     double          m_valDouble;
335     const wxChar*   m_valCString;
336     bool            m_valBool;
337 #if defined(wxJSON_64BIT_INT)
338     wxInt64         m_valInt64;
339     wxUint64        m_valUInt64;
340 #endif
341     };
342 
343 //
344 // access to the (unsigned) integer value is done through
345 // the VAL_INT macro which expands to the 'long' integer
346 // data member of the 'long long' integer if 64-bits integer
347 // support is enabled
348 #if defined(wxJSON_64BIT_INT)
349 	#define VAL_INT  m_valInt64
350 	#define VAL_UINT m_valUInt64
351 #else
352 	#define VAL_INT  m_valLong
353 	#define VAL_UINT m_valULong
354 #endif
355 
356 
357 
358 // class WXDLLIMPEXP_JSON wxJSONRefData : public wxObjectRefData
359 class WXDLLIMPEXP_JSON wxJSONRefData {
360     // friend class wxJSONReader;
361     friend class wxJSONValue;
362     friend class wxJSONWriter;
363 
364  public:
365     wxJSONRefData();
366     virtual ~wxJSONRefData();
367 
368     int GetRefCount() const;
369 
370     // there is no need to define copy ctor
371 
372     //! the references count
373     int               m_refCount;
374 
375     //! The actual type of the value held by this object.
376     wxJSONType        m_type;
377 
378     //! The JSON value held by this object.
379     /*!
380     This data member contains the JSON data types defined by the
381     JSON syntax with the exception of the complex objects.
382     This data member is an union of the primitive types
383     so that it is simplier to cast them in other compatible types.
384     */
385     wxJSONValueHolder m_value;
386 
387     //! The JSON string value.
388     wxString            m_valString;
389 
390     //! The JSON array value.
391     wxJSONInternalArray m_valArray;
392 
393     //! The JSON object value.
394     wxJSONInternalMap   m_valMap;
395 
396     //! The position of the comment line(s), if any.
397     /*!
398     The data member contains one of the following constants:
399     \li \c wxJSONVALUE_COMMENT_BEFORE
400     \li \c wxJSONVALUE_COMMENT_AFTER
401     \li \c wxJSONVALUE_COMMENT_INLINE
402     */
403     int               m_commentPos;
404 
405     //! The array of comment lines; may be empty.
406     wxArrayString     m_comments;
407 
408     //! The line number when this value was read
409     /*!
410     This data member is used by the wxJSONReader class and it is
411     used to store the line number of the JSON text document where
412     the value appeared. This value is compared to the line number
413     of a comment line in order to obtain the value which a
414     comment refersto.
415     */
416     int               m_lineNo;
417 
418     //! The pointer to the memory buffer object
419     /*!
420      Note that despite using reference counting, the \b wxMemoryBuffer is not a
421      \e copy-on-write structure so the wxJSON library uses some tricks in order to
422      avoid the side effects of copying / assigning wxMemoryBuffer objects
423     */
424     wxMemoryBuffer* m_memBuff;
425 
426     // used for debugging purposes: only in debug builds.
427 #if defined(WXJSON_USE_VALUE_COUNTER)
428     int         m_progr;
429     static int  sm_progr;
430 #endif
431 };
432 
433 
434 
435 #endif            // not defined _WX_JSONVAL_H
436 
437 
438